|
该用户从未签到
|
2、状态管理* T! Z( _. y8 W$ i6 `
1)什么是状态管理+ L( Q7 j$ @. X* `
将客户端(一般是浏览器)与服务器之间的多次* a, C& \0 I. N9 p) c. K) }9 d
交互当作一个整体来看待,即将多次操作所涉及的
2 T$ a: K9 q9 ^/ u! r/ a 数据记录下来。" n& r3 B3 J$ y. M. T2 \
2)怎样进行状态管理( @. r, x/ r) g" W8 Z# O* V0 k
第一种方式,在客户端管理用户的状态% g$ y; U; A' x& i" j' n" |
(cookie)。$ e* d; m) V' V& M
第二种方式,在服务器端管理用户的状态
$ E/ m# r7 t; L' T! g (session)。
* g3 ^% l |2 z. O5 H 3)cookie! Y+ v7 w% M6 y7 E- _( E* Q
a,什么是cookie?
% `2 K6 w! p* c: V5 C; e/ @% s 浏览器在访问服务器时,服务器将一些数据
" G$ u" m# I6 W7 m. d4 L; b 以set-cookie消息头的形式发送给浏览器。浏览7 @% \2 I/ ^* h
器会将这些数据保存起来。当浏览器再次访问
5 G: o& u5 }! k. n0 @ 服务器时,会将这些数据以cookie消息头的形式
6 D! `# Z2 L* ^ 发送给服务器。通过这种方式,可以管理用户的
$ s8 j( \# h' [6 k 状态。% y8 n% W8 ^; R) U
b,怎样创建cookie?
$ e+ E. a) N4 t Z Cookie cookie = new Cookie(String name,0 X% p5 U9 A& C1 T: {3 U* x8 A
String value);
0 S( G7 y8 ]3 o response.addCookie(cookie);
0 N# ?2 ?, [ K) u c,查询cookie( G1 n2 u' I+ |$ [) E
//如果没有cookie,则返回null。$ t/ S7 f% K/ ]9 h/ s; D
Cookie[] cookies = request.getCookies();
( ^. U1 Q- g2 V String name = cookie.getName();
d, x, n& n9 J8 h/ Z4 o String value = cookie.getValue();3 C# m$ A6 l' \( M+ ^6 e
d,cookie保存时的编码问题1 g/ ` s! ~5 D4 L+ }- X) O9 {; q5 _
cookie的值只能是ascii字符,如果是中文,
. T8 ^. r# a; w5 S) H0 j9 Q; F 需要将中文转换成ascii字符形式。
5 c+ G- ]( @" J# ~; O& p 可以使用URLEncoder.encode()方法和: D9 \, A1 J+ O5 |8 z
URLDecoder.decode()方法来进行这种转换。2 M/ W/ z* w) Q6 P
e,cookie的保存时间' H8 d; a3 L4 z( g
cookie.setMaxAge(int seconds);# b C( }- A8 w6 t
seconds > 0:浏览器会将cookie以文件的方式0 Y0 c. M( r: _1 K. M
保存在硬盘上。在超过指定的时间以后,会删除
) A) U, F9 a6 }7 e0 _9 m6 ~2 D 该文件。0 v1 p$ o, s- D- m. B8 Y6 U
seconds < 0:默认值,浏览器会将cookie保存. ~6 \+ c- O! e, k, |6 \
在内存里面。只有当浏览器关闭之后,才会删除。
" j0 b+ A& y( z4 b( B seconds = 0:删除。9 e$ K) h( V P* X7 u. v8 x
f,删除cookie. Z. g" o J+ g- [; P* l
比如要删除一个name为"username"的cookie。% ?1 {4 B$ u% V* R* v1 |
Cookie c = new Cookie("username","");
& t9 u( S( T* C+ o9 j c.setMaxAge(0);, B" y1 Z( P6 n. A9 o
response.addCookie(c);
! `" Q% A# Y+ }* i1 V2 ~ g,cookie的路径问题
2 R$ P( l4 W- q5 Z( Q: d" h$ D 浏览器在向服务器上的某个地址发送请求时,
' t1 H8 J. l2 S2 O; _5 n' G6 z1 ? 会先比较cookie的路径与向访问的路径(地址)是. u4 e( V' ]% ]5 S3 ]
否匹配。只有匹配的cookie,才会发送。6 j1 K7 a, I, h( ]: V" g
cookie的路径可以通过( [7 z; R& S& W X
cookie.setPath(String path)方法来设置。
3 M, h- t0 C/ [" |: H% X 如果没有设置,则有一个缺省的路径,缺省的8 w6 d2 D0 j% O5 b
路径是生成该cookie的组件的路径。
. y* C1 X: J" G) I 比如: /appname/addCookie保存了一个cookie,
) S; J" I( S) u+ o, r2 g 则该cookie的路径就是/appname/addCookie。' b, N# w" N% {+ R: ~& k; G# E( ^
Y9 |5 J/ V; [+ {$ W
规则:
( [2 ]! h. Q& O( [ cookie的路径必须是要访问的路径的上层目录
1 h0 y6 X" Y& E; k4 L' \ 或者是与要访问的路径相等,浏览器才会
1 s @2 R0 G9 l" K1 H: G+ s# H 将cookie发送给服务器。
3 l7 q O4 t4 j; |) b# w- z7 F
; J) G6 V! I5 l9 R( \ 一般可以设置setPath("/appname"),表示访问7 |" m! v) x, c4 q
该应用下的所有地址,均会发送cookie。
& b/ W8 ?! |/ h0 N& v h,cookie的限制
# }8 I* o6 s: k- l cookie可以禁止+ S+ r8 d- q4 g ~: l
cookie的大小有限制(4k左右)
: u7 D: s* ~1 ^, s cookie的数量也有限制(浏览器大约能保存300个)
# `$ L7 `8 h x2 `- @$ w cookie的值只能是字符串,要考虑编码问题。
9 C2 v+ }! N( R! _; m cookie不安全
: R- f) }' W5 _& B, R- q 练习:+ r& H V* \ k- A
写一个Add_FindCookieServlet,该servlet先查询
- J: h, o' X/ }, R 有没有一个名叫name的cookie,如果有,则显示4 q! I$ g/ m5 q& ~: T
该cookie的值,如果没有,则创建该cookie(
9 t4 w) O3 s+ d8 ? cookie的名字:name,cookie的值:zs)。2 ?, J2 S7 F. b8 m1 T6 f
- v! y# @/ B. j
9 n! [% O: u2 u$ j; y: ?
4)session 7 m8 {* Y9 d" o& R5 ]) X, ^( w# H. N& [. a
a,什么是session?6 q) U# z9 f: g+ Y
浏览器访问服务器时,服务器会创建一个session
" P% \9 E8 o0 r 对象(该对象有一个唯一的id, 一般称为sessionId)* [; c1 L8 B9 H$ T- C/ C
。服务器在缺省情况下,会将sessionId以cookie( k' B0 g% j4 j! y Y
机制发送给浏览器。当浏览器再次访问服务器时,' K: j3 c/ ]' S
会将sessionId发送给服务器。服务器依据sessionId4 K4 y9 H5 T9 E p' ]
就可以找到对应的session对象。通过这种方式,$ s2 m, o8 M$ P$ ?$ j
就可以管理用户的状态。9 h, O m; ^/ Q1 G
b,如何获得session对象+ V/ J! Q _ Z
方式一:' V1 u2 @7 ^7 f2 h
HttpSession session = - x7 o! U: F4 }! |6 C4 S6 ]& D6 v
request.getSession(boolean flag);
- u; e9 o3 N$ a9 l2 i8 ?4 r6 i 当flag = true:7 Z" m# \3 f' y$ r/ @# h
服务器会先查看请求中是否包含sessionId,; d5 p' X3 |9 s6 P6 V+ {+ c
如果没有,则创建一个session对象。
* _1 d: M( {; L; ~) q; n1 | 如果有,则依据sessionId去查找对应的% d4 e6 z/ w$ s" h: @
session对象,如果找到,则返回。
7 E! e, i# Q( b1 Z 如果找不到,则创建一个新的session对象。; ^9 R9 ], h9 ?
当flag = false:" A! }( Q* X- q2 O
服务器会先查看请求中是否包含sessionId,
' q$ ]0 ?) l& J4 S1 T3 Q+ @7 d7 F6 O 如果没有,返回null。
" B1 [6 j: Y/ P8 T3 k 如果有,则依据sessionId去查找对应的- q5 W9 K+ q9 [: W& B% G
session对象,如果找到,则返回。9 n2 @" N3 N) V* W
如果找不到,返回null。) O; L* j: g( w% x4 h
方式二:0 H* X1 K$ j+ i: I3 o6 D& T, L
HttpSession session =
) Z" ]2 y1 ]/ w% `+ p; U+ o; D2 K+ k request.getSession();
) h* C6 y$ q& N1 a6 ~ 与request.getSession(true)等价。
+ t. A9 |: t- g: g" I i: m c,HttpSession接口提供的一些方法
0 x2 V5 ~; L) @ //获得sessionId。
+ ^; [( z9 `: f String session.getId();
% Y- C1 g. O( M6 F3 U5 b //绑订数据& d0 ?# h+ k! ]8 g9 Y$ a1 f
session.setAttribute(, A; P( Q( t# s; s" \ B! ~7 [0 G
String name,Object obj);
( F/ a4 f4 u) ^" n5 D //obj最好实现Serializable接口(服务器
/ U' J/ `- j ~9 A8 D 在对session进行持久化操作时,比如钝化
" S! \& B# r; C, `2 H 、激活,会使用序列化协议)。/ x8 w# M, j# f* c
Object session.getAttribute(String name);4 X4 J& q% L% J$ n. L' |
//如果name对应的值不存在,返回null。
! s6 _7 T6 x1 _0 a session.removeAttribute(String name);
) L5 H: F( x* I$ ~8 t" x" q3 V( M d,session超时
7 j8 U6 u9 p, d5 J& i' Z 服务器会将超过指定时间的session对象, ?5 N& v5 P' U+ j. _/ g
删除(在指定的时间内,该session对象没有/ K' l' \7 u& u+ k: Y( B O) w5 B
使用)。. I x9 p) U: P! a
方式一:
( j0 k& y8 v8 t- z( w( D session.setMaxInactiveInterval(
5 g& }, e& Q3 j* I int seconds);" }9 L/ e* q* w7 j
方式二:
/ e! B2 Q7 ~* | 服务器有一个缺省的超时限制,可以9 e$ \3 D+ ?2 V8 M8 U/ {
通过相应的配置文件来重新设置。
- P/ g" v7 K# \. R% N3 \7 o 比如可以修改tomcat的web.xml(9 c7 c$ O: C9 f) s$ V* q! h9 D: t
tomcat_home/conf下面)。: ~; b6 H' C/ x, j( E( q: F+ o# [
<session-config>
- R5 R7 N% \6 {3 e' } <session-timeout>30</session-timeout>" }, E8 o* e$ K. P) p4 x. |
</session-config>& {* c8 w. m Z
另外,也可以只修改某个应用的web.xml。7 N( j; d) {4 o7 D% y n$ Y
e,删除session, J* O$ \8 U5 | T# D5 x2 W, \
session.invalidate();. `) h( q: I/ F7 W- N
6 I0 x, S& ]8 T. _4 \. L8 ^* M; C
案例:4 L1 r. [! _ s' y8 K; v% d
session验证
* E: K0 d% B& W j$ T0 [ step1 在登录成功之后,在session上绑订一些数据。% t4 E) C" `7 E* @9 a( x Q3 h
比如:
8 G& L2 \# U; `( p. | session.setAttribute("user",user);+ s- i+ x% e& m: I# I2 G* U' }
step2 在访问需要保护的页面或者资源时,执行- `( z2 o1 z% a2 f+ g; }' f4 l
Object obj = session.getAttribute("user");$ x5 k$ J- G0 z
如果obj为null,说明没有登录,一般重定向到
3 T. o7 T4 @/ G6 v 登录页面。
: Y5 D4 y$ p/ j$ y8 ]( T P+ d |
-
总评分: 帮币 + 5
查看全部评分
|