该用户从未签到
|
2、状态管理; X# T) v% g5 I/ f
1)什么是状态管理0 H" B, d/ x0 \/ {9 N
将客户端(一般是浏览器)与服务器之间的多次8 J- B8 o! t% a$ ]
交互当作一个整体来看待,即将多次操作所涉及的
9 d" R: A; k# w! v' E9 v 数据记录下来。
3 h2 U, M( X; {$ I7 b 2)怎样进行状态管理
- T% u$ V7 D: C0 }6 A" L7 U 第一种方式,在客户端管理用户的状态
, N( c& S5 v4 {: O: B (cookie)。3 @. a2 Q1 R7 n# |2 @
第二种方式,在服务器端管理用户的状态2 P2 V2 A( Y: K' s
(session)。6 r" Z, i! x5 U6 `) E Q4 C# a
3)cookie8 ]9 X4 c8 r' \
a,什么是cookie?
/ \0 v& j8 a. C+ g0 W+ L 浏览器在访问服务器时,服务器将一些数据' N( u% g( v/ B* M' `$ r/ u6 Q ~
以set-cookie消息头的形式发送给浏览器。浏览+ F. H1 z4 j$ B8 y$ w8 s9 e, G
器会将这些数据保存起来。当浏览器再次访问
( V7 b8 Q s. p, z4 F& N 服务器时,会将这些数据以cookie消息头的形式
i& W& i- P7 O9 f 发送给服务器。通过这种方式,可以管理用户的1 p5 v7 E; P2 P
状态。
3 h! a# j: L0 b* A& l/ Q- t5 T b,怎样创建cookie?
9 _# ]( m. f% T+ O2 \$ S Cookie cookie = new Cookie(String name,
& F4 V0 j6 X8 q8 h) R String value);) b2 q- o) V2 [* K& d8 c
response.addCookie(cookie);* g: E; G/ J: l& [$ `
c,查询cookie
3 ?: T- ?9 E$ b% S9 z$ ^2 q //如果没有cookie,则返回null。
! ~/ u4 h1 v5 o9 _1 ~( F6 I9 M Cookie[] cookies = request.getCookies();' s2 W+ N8 c/ l4 `
String name = cookie.getName();' x0 Y( x7 ]' H4 e5 u# C
String value = cookie.getValue();& L& `- q4 n* b9 l2 d
d,cookie保存时的编码问题* ?) [! y" }, O$ b x
cookie的值只能是ascii字符,如果是中文,& q0 Q7 O: l5 ^) f! @( F
需要将中文转换成ascii字符形式。
9 `8 h) q, |( S0 P; y H' w( \; @$ X 可以使用URLEncoder.encode()方法和+ ~- y1 Y0 j* A. y# p; u: j! _+ {
URLDecoder.decode()方法来进行这种转换。
7 q3 b& L. E* A+ o% L) \, ~ e,cookie的保存时间
3 w# G$ g" d J* v% v cookie.setMaxAge(int seconds);# \! I, T* \9 a; D* @; {
seconds > 0:浏览器会将cookie以文件的方式8 Y# c; M& U$ D# C; ]
保存在硬盘上。在超过指定的时间以后,会删除) c( w4 E" V& y6 k
该文件。' ]$ K0 Y* m9 d2 v+ L/ H
seconds < 0:默认值,浏览器会将cookie保存7 k: c2 X: Z' n
在内存里面。只有当浏览器关闭之后,才会删除。
' _& ~5 E0 j6 N4 K: X9 X0 L5 Y. i seconds = 0:删除。/ R) }( S9 F; I' a: F) N% F
f,删除cookie
: l3 Y* S2 v* t/ {; k0 X 比如要删除一个name为"username"的cookie。
6 ]' a( k4 P8 K3 P0 I, m Cookie c = new Cookie("username","");$ t7 R' @. L+ O6 b2 Z$ ~( u
c.setMaxAge(0);% _$ m& S4 E. P: N$ V
response.addCookie(c);1 q) v, H3 t6 F% t, p+ l' q
g,cookie的路径问题
0 p) m9 y6 `4 f9 K1 |$ q9 K 浏览器在向服务器上的某个地址发送请求时,
+ @" E; x! I6 O% q, N. M 会先比较cookie的路径与向访问的路径(地址)是
2 U3 [/ F( E9 q# Z' ~ 否匹配。只有匹配的cookie,才会发送。7 o& D# g9 z- ^7 v
cookie的路径可以通过+ l, C8 r. ^+ t# a
cookie.setPath(String path)方法来设置。9 H% {- w( b V8 \: H" s4 F
如果没有设置,则有一个缺省的路径,缺省的
8 }" k7 @; j: ~% l! G 路径是生成该cookie的组件的路径。# }! T- ]+ w$ d7 |
比如: /appname/addCookie保存了一个cookie,% a- L# N; m1 V: u
则该cookie的路径就是/appname/addCookie。
0 `" ]" w; h4 U 0 ~3 W" x5 m" n
规则:
$ v7 g: \' c* \+ k. r9 j- |- [ I* I8 T cookie的路径必须是要访问的路径的上层目录
5 B4 w0 x4 d* `# Z8 z9 [ 或者是与要访问的路径相等,浏览器才会/ R: F! d: [4 ~% M o: Z
将cookie发送给服务器。4 b) J5 r6 r4 Q+ y! ~6 v
) [: y- z5 Q$ i$ P
一般可以设置setPath("/appname"),表示访问
0 f; i/ ~' I' t. f. J: b 该应用下的所有地址,均会发送cookie。
4 l) X1 p" K# s& ?/ x3 q: z* t# j; e& k h,cookie的限制
, S2 m: I. |. b9 C* J( n) R cookie可以禁止
# O! b2 G& Y8 E" K# i* i cookie的大小有限制(4k左右)
: R4 P7 p0 k. w4 O0 J8 R) e cookie的数量也有限制(浏览器大约能保存300个) / A7 a, G1 r/ Y
cookie的值只能是字符串,要考虑编码问题。- Q r- ^0 g: s5 T G* R) L) f
cookie不安全
_% ?' Y3 Q* ?$ f. N 练习:* `: Z6 G* m7 b1 |* |
写一个Add_FindCookieServlet,该servlet先查询* l1 V7 N0 u+ T* F! K- ?7 ^
有没有一个名叫name的cookie,如果有,则显示: b; ^' x3 x. s* i
该cookie的值,如果没有,则创建该cookie(/ a; ^2 I4 F& D& y
cookie的名字:name,cookie的值:zs)。
4 H7 f7 W0 w4 p) s
8 t% N4 J! }7 D1 D* l
7 P1 g) ~1 {! B, ~6 G. ?4 l 4)session * {% K! k5 z9 S$ `
a,什么是session?( ^$ D2 r& X2 K( y9 c0 [$ b) ~
浏览器访问服务器时,服务器会创建一个session
1 y" E. w+ I/ Q+ Z 对象(该对象有一个唯一的id, 一般称为sessionId)7 \1 F2 ]/ {$ _, Y7 N& T
。服务器在缺省情况下,会将sessionId以cookie. x: |% C6 L i: h4 V
机制发送给浏览器。当浏览器再次访问服务器时,
# m% t3 J3 w0 h. j3 w 会将sessionId发送给服务器。服务器依据sessionId" V2 H5 a; U: @0 Z' m
就可以找到对应的session对象。通过这种方式,' F7 H. F5 w+ f, h' n2 E
就可以管理用户的状态。9 K( r8 c& ?1 N& v3 U
b,如何获得session对象
r6 s$ V+ s" h4 W 方式一:# x4 l- ?) a8 C; z6 B* K( f U
HttpSession session = 0 M d: w; N* W5 b2 k! W% x7 |
request.getSession(boolean flag);& C2 y( F( u* E u- s0 o* [
当flag = true:
# } \; i, x; N$ k# N 服务器会先查看请求中是否包含sessionId,; y/ @2 R* e; I) d" g2 B4 K
如果没有,则创建一个session对象。: J& @& L2 U+ n7 {
如果有,则依据sessionId去查找对应的9 A3 J. m7 f8 |4 R
session对象,如果找到,则返回。$ }5 {2 v0 j$ \
如果找不到,则创建一个新的session对象。
* c. Z4 e9 \" r 当flag = false:
$ D$ X( Y# E* y3 E1 Y 服务器会先查看请求中是否包含sessionId,
$ O+ f. X1 M' S$ N 如果没有,返回null。: H. A: L, T4 H
如果有,则依据sessionId去查找对应的
/ l" _- @8 B* d9 f3 K4 Y session对象,如果找到,则返回。
1 {% Q- ]% }* K# S( i: t5 u+ | 如果找不到,返回null。
0 m! r4 T8 u$ U1 C# D9 z 方式二:
Q( {% o, e( _: G* {# \ HttpSession session = 6 s* W! V# o S" }. v
request.getSession();; H0 U- n* Y# @3 E* G! H4 G
与request.getSession(true)等价。
4 u6 l. f1 X( T/ @3 H c,HttpSession接口提供的一些方法& s: y; s- ?8 l: k+ ?, D' Y
//获得sessionId。% }3 P$ W3 i% c4 U
String session.getId();
6 K O4 H4 f: X/ D //绑订数据
: M7 R% r- r0 u( }0 g% M8 \ session.setAttribute( l% m; J! j9 ?# n
String name,Object obj);
9 ^2 @9 V. ]! k //obj最好实现Serializable接口(服务器
9 |* w5 f6 j5 s! Y( @; d. C9 m 在对session进行持久化操作时,比如钝化
9 s1 {( }( j9 ]6 J 、激活,会使用序列化协议)。
; U& Y1 x( @4 w' u Object session.getAttribute(String name);
) \$ W# z& x2 T) i! O //如果name对应的值不存在,返回null。
: m2 z* z9 X) L, B5 x# S% [. a$ i session.removeAttribute(String name);/ S5 u5 z& @ P6 r! k1 D, J
d,session超时/ J( [! }# d, S6 a
服务器会将超过指定时间的session对象
/ g+ T5 @! X( A/ o8 m 删除(在指定的时间内,该session对象没有
4 ~ A9 o# Y: \7 j 使用)。
1 i: }' [/ w9 H; Y) V 方式一:
9 l: {+ o* f# @! m6 _5 B4 k, U- y0 O6 x session.setMaxInactiveInterval(
0 u6 j. V# q* x: M7 x+ x int seconds);* k9 ?# R0 e7 t1 O; \: \; w( L
方式二:
# n" S- t; G6 _1 _) W; Q3 ?! u 服务器有一个缺省的超时限制,可以
' \% q: C8 h5 e0 @. q) l 通过相应的配置文件来重新设置。
' I6 |) K5 `3 W; u0 l7 i 比如可以修改tomcat的web.xml(: U. N1 L+ h' F) P6 b7 F3 v
tomcat_home/conf下面)。
" |8 q2 W, P, Q& X <session-config>
' {5 J: } f6 l, y$ b <session-timeout>30</session-timeout>9 m5 I# f" Y$ H9 @+ b7 k5 y% m+ S
</session-config>
% ]+ r- j; R: E& k3 l3 w4 ^ 另外,也可以只修改某个应用的web.xml。7 _: d3 X4 d W1 U$ ~
e,删除session
2 a" A3 S+ P8 c/ z" ^' | session.invalidate();
. _; C) u5 ~) L9 _3 M
5 \6 `1 F' g% y, s- \6 u9 A6 q 案例:
) B- w- C' i5 [$ n8 N+ y* Y session验证1 T q% r& ?0 c# K
step1 在登录成功之后,在session上绑订一些数据。" _" U+ w& Z8 P
比如: f) j; e2 z/ r; ~0 u e& }% U- N* i: c
session.setAttribute("user",user);
5 W' V8 l% E% w step2 在访问需要保护的页面或者资源时,执行, y0 f2 ~6 U1 x9 N( d
Object obj = session.getAttribute("user");% p# D( @8 C# ~* V) M
如果obj为null,说明没有登录,一般重定向到8 o; P! J- r& J1 ?$ D5 S" Y$ U
登录页面。
# p8 C; f* d( `# ] |
-
总评分: 帮币 + 5
查看全部评分
|