该用户从未签到
|
2、状态管理
2 Y; o' }/ Z+ ^/ y 1)什么是状态管理. g) @9 W. ~5 J8 l5 s& g9 p
将客户端(一般是浏览器)与服务器之间的多次/ L$ ^& A: U1 J6 x' E
交互当作一个整体来看待,即将多次操作所涉及的% O3 C* h. ^4 H. ~2 L5 ^8 n
数据记录下来。
5 y# q) s2 t! C, A7 Z 2)怎样进行状态管理
( U8 T4 M( ] E9 x" y 第一种方式,在客户端管理用户的状态
6 j# @& n1 h3 E (cookie)。4 ^* n/ M* g# X! j; E* [
第二种方式,在服务器端管理用户的状态
/ y9 Q6 e, Z$ ?) e (session)。 \, ^* D6 J( v! g3 J B3 E1 b0 R
3)cookie) L/ W/ M2 _9 F- }8 O* ^4 A# n2 R
a,什么是cookie?2 w) G% d: @; P. F Z* {) e
浏览器在访问服务器时,服务器将一些数据: X7 r+ n6 I. I7 m5 `) ~4 E
以set-cookie消息头的形式发送给浏览器。浏览
! y9 j" l1 B6 k/ q0 U 器会将这些数据保存起来。当浏览器再次访问) I$ o' E8 k$ [* o' o, u
服务器时,会将这些数据以cookie消息头的形式
; D- W8 v5 p1 |5 K4 g2 Y( L 发送给服务器。通过这种方式,可以管理用户的
2 U2 B* G4 W6 X+ f5 l 状态。+ J9 B% Z: E7 n+ w$ h% k! C9 O
b,怎样创建cookie?9 m- j% `# K* E: b
Cookie cookie = new Cookie(String name,1 O1 t# w, G {5 p: }$ P
String value);
' N2 n# \5 i5 S3 i# T! Q6 e& W; } response.addCookie(cookie);8 g: y, D# X# w$ u7 v* W) Z8 K
c,查询cookie, S+ ?5 R' b) J6 s5 v9 j) g1 J [
//如果没有cookie,则返回null。
% |2 z; V# n3 f5 j% D/ m9 t3 N3 `& _& @ Cookie[] cookies = request.getCookies();, s" X8 U: w% T- ]. r
String name = cookie.getName();4 N; F) u" z c9 l& W8 k+ X
String value = cookie.getValue();0 P4 P. k6 j8 K5 p7 K6 h
d,cookie保存时的编码问题
. T7 u* Z( l; w/ Q5 M cookie的值只能是ascii字符,如果是中文,
: r3 F/ `" a# J3 {6 ^1 r( M+ Y& i 需要将中文转换成ascii字符形式。. J6 }1 m$ v7 G" }- ?9 m+ o
可以使用URLEncoder.encode()方法和& A. e; C8 E, ^% @! ^4 t3 F- v. E
URLDecoder.decode()方法来进行这种转换。
4 X& u: L) N) t( l. }) f3 g e,cookie的保存时间. ?5 h+ t u1 H! ^: h( n; `
cookie.setMaxAge(int seconds);
8 [1 R# j0 D, c* u6 c3 a6 V# C seconds > 0:浏览器会将cookie以文件的方式
A+ L9 o% b. b1 M% a4 \ 保存在硬盘上。在超过指定的时间以后,会删除4 N7 W; Z& |$ m* @4 W
该文件。+ j5 G$ |; i2 _
seconds < 0:默认值,浏览器会将cookie保存
# u, {- V& V; T# p) g6 T9 O 在内存里面。只有当浏览器关闭之后,才会删除。
; K8 W5 P6 ^" D seconds = 0:删除。
5 ]; A" m H7 | f,删除cookie
. F: L, ^7 h0 [- z! i 比如要删除一个name为"username"的cookie。7 d7 Z5 D, E# O; a y: I# r
Cookie c = new Cookie("username","");
! P( F% u+ e/ `7 v7 W c.setMaxAge(0);
$ ^! {7 D- H# r8 q0 \; I response.addCookie(c);9 a8 `2 [; K A9 t6 u- z
g,cookie的路径问题5 X" g, k K: V) a& r
浏览器在向服务器上的某个地址发送请求时,; i6 ?6 T5 N3 T+ G1 H7 A5 h+ L+ o! @
会先比较cookie的路径与向访问的路径(地址)是$ a" k I, a$ ?; B9 E! B
否匹配。只有匹配的cookie,才会发送。) D) \7 b' S, i. @% d0 Q
cookie的路径可以通过3 _6 U2 V2 M, o) a
cookie.setPath(String path)方法来设置。
5 E! P" R. P( N+ c+ G; h9 c) D n 如果没有设置,则有一个缺省的路径,缺省的
/ F4 {) L% [2 X' V$ {) Y 路径是生成该cookie的组件的路径。) o( Q4 T8 J* h g/ l
比如: /appname/addCookie保存了一个cookie,
# }6 G# y% J. [7 @0 ] 则该cookie的路径就是/appname/addCookie。; v/ E; H& k& d: g* I
. ]" Y W$ B( L+ Y& g5 T/ T
规则:0 y/ M: r9 H* ]. ^8 R% W
cookie的路径必须是要访问的路径的上层目录, H2 o$ Y# b5 M) B
或者是与要访问的路径相等,浏览器才会0 X; y# J- U+ H. V- j
将cookie发送给服务器。2 n7 G4 ?+ P) f, ~
1 [. ^3 K/ j8 B3 K: g( U
一般可以设置setPath("/appname"),表示访问
3 G$ W# }6 _1 q% ?- g1 `0 O# A9 Y 该应用下的所有地址,均会发送cookie。4 B W0 u/ P) ?# j" {" P! o
h,cookie的限制7 ]# L2 i3 q, K1 ?; \2 F* n% J
cookie可以禁止. X% @3 z# k& |% K- M% I3 K2 Y; K
cookie的大小有限制(4k左右)
: ^: M7 h! O7 k7 W0 i* h* g! m cookie的数量也有限制(浏览器大约能保存300个)
& N( T* D2 B& y1 N" g5 v" w cookie的值只能是字符串,要考虑编码问题。
) F% O" a) D, z3 ^, W% K* x4 B cookie不安全
/ W3 X. v" ~/ X8 O 练习:
. Z( f" u& F+ s 写一个Add_FindCookieServlet,该servlet先查询
! ?2 v& O' C9 T$ f( ?& T 有没有一个名叫name的cookie,如果有,则显示6 o2 Y( I6 E4 U1 {& i% I u* C
该cookie的值,如果没有,则创建该cookie(8 X8 Q6 w" D4 n! z" z$ H
cookie的名字:name,cookie的值:zs)。7 M) l/ i; N- c' d4 b- ?
9 W, R# a$ T7 w# {5 ~% X6 X
2 Y7 n5 D. X. s0 L
4)session
4 u3 |* t m! h) n" Q a,什么是session?
* r% U' H( L( @! v" ] 浏览器访问服务器时,服务器会创建一个session r! F+ J/ U5 _) _
对象(该对象有一个唯一的id, 一般称为sessionId), \) I7 y0 P) l. n( h5 L& |
。服务器在缺省情况下,会将sessionId以cookie
' I& r1 A, C0 q) r1 F 机制发送给浏览器。当浏览器再次访问服务器时,
J& A) @$ e4 P0 S( ]. G 会将sessionId发送给服务器。服务器依据sessionId R: F R' [* `, d! J& F9 G4 U9 d
就可以找到对应的session对象。通过这种方式,( ~5 b0 @( G/ [; I' B% J. P4 c
就可以管理用户的状态。
0 W% C% j, r/ I4 D# }" ` b,如何获得session对象
) T; G/ c; H# G$ B- {6 j+ x0 B 方式一:
* H; Z; K' U: T$ q3 B1 J) } HttpSession session =
$ \' `7 e: f" w1 r; X! J, c request.getSession(boolean flag);, }/ E+ b, \" l0 e9 w& A5 {
当flag = true:# X' R; [& z% u6 |
服务器会先查看请求中是否包含sessionId, b Q$ `& f, Z. x9 L6 m8 @
如果没有,则创建一个session对象。! W# }0 A0 |$ D, c( }& U5 ]4 b
如果有,则依据sessionId去查找对应的
2 ^7 z$ ~' q1 C! B! c; k; M session对象,如果找到,则返回。2 i: B; Z4 t" F
如果找不到,则创建一个新的session对象。) L! ]+ `% e: C! l) K- _( O
当flag = false:
8 G- `) `8 q9 P3 K" ~ 服务器会先查看请求中是否包含sessionId,4 o; c7 `+ i% X/ e6 }- X8 O! z0 y
如果没有,返回null。' |! f# v8 j' @
如果有,则依据sessionId去查找对应的0 Y$ c& g( i( f2 b& D! a1 w
session对象,如果找到,则返回。7 d/ b! M3 r% {; M; H* \
如果找不到,返回null。. E- u& W- a1 \) z( t) s
方式二:1 Z r$ d w) \7 W" e# q2 _
HttpSession session = }) e# E& b2 R
request.getSession();
# M, J1 r2 z( h: `6 @1 l 与request.getSession(true)等价。1 k4 e4 X% J$ k! ~. Y# p
c,HttpSession接口提供的一些方法: G% ?! Q5 {. j: b8 O/ k
//获得sessionId。
6 C7 R7 K. a. z& O String session.getId();
( Z% K/ O: e. ]+ M //绑订数据$ s( \' p6 u& U+ @) h
session.setAttribute(# j# y& A. X- E. \$ g5 j1 P! _ g
String name,Object obj);% Y' a6 `' y4 C8 d' e
//obj最好实现Serializable接口(服务器
4 e; A% M3 O, z/ g 在对session进行持久化操作时,比如钝化: p/ w6 f, L5 t1 h1 ~' U6 [' [! `, P
、激活,会使用序列化协议)。
$ Q" H! @3 b/ j; I; s. k( |& S, a Object session.getAttribute(String name);
: ]5 G6 S E# W3 d/ }5 z //如果name对应的值不存在,返回null。) G8 ]" O: g7 i3 f' |% [
session.removeAttribute(String name);7 G( d, F6 {6 W" d# X9 |8 C
d,session超时
3 m0 W5 q8 D1 a, M$ U* u) i 服务器会将超过指定时间的session对象7 y* @( x* e7 f5 \/ J: ~
删除(在指定的时间内,该session对象没有
! ^) u4 _; V# A* N 使用)。
+ m. i* q: |2 e( T8 v: L R 方式一:
1 t( u% \& w8 s session.setMaxInactiveInterval(
' ^7 d9 Q8 K) \" ^; ~ int seconds);
/ B/ }- S# D$ A) ] 方式二:
* X& d2 K* w' K! c+ p, @ 服务器有一个缺省的超时限制,可以
: r3 v: [, [! q: F- J 通过相应的配置文件来重新设置。
! D- u( C' d8 k7 G 比如可以修改tomcat的web.xml(
" m; V- B c5 e- L" q tomcat_home/conf下面)。
7 u- {% z7 d2 r. k4 s, G4 } <session-config>) Y9 `' }* \- g
<session-timeout>30</session-timeout>
2 ?8 b' l; b8 g' @ </session-config>5 e% @5 D3 E# L
另外,也可以只修改某个应用的web.xml。
- D% i' X g* o4 \) V e,删除session
. q' s6 f" ?- l1 g! m( p; q4 a6 l session.invalidate();$ y3 J5 e& \; B/ m8 Z9 i# m
6 P/ K: J* ]+ v: Q; s9 N1 a 案例:
" Y3 q* L! F) X- B* O session验证
2 r w# }# n! P* U) J step1 在登录成功之后,在session上绑订一些数据。
3 u+ X' q1 h: V) E r( ?5 i 比如:
+ [7 b' B$ C2 c4 g session.setAttribute("user",user);
! Y: H. ]! ]5 z& R step2 在访问需要保护的页面或者资源时,执行
0 B0 O4 x/ r* |' o$ P9 [ Object obj = session.getAttribute("user");
9 w o1 Q1 u: a ~; H 如果obj为null,说明没有登录,一般重定向到
# v/ U( F E c b6 N8 j& y# a) r 登录页面。
?. b1 W, z/ ^) y$ K2 A7 f |
-
总评分: 帮币 + 5
查看全部评分
|