|
该用户从未签到
|
2、状态管理% \" e3 F6 @ F
1)什么是状态管理
6 I+ r2 Y! a5 w 将客户端(一般是浏览器)与服务器之间的多次! p/ T( \) X% T) _! f
交互当作一个整体来看待,即将多次操作所涉及的
" B5 z# o7 R/ u F, a 数据记录下来。7 Q4 u7 D! X* _/ g1 R' u& u5 a
2)怎样进行状态管理
& q2 X* i( o2 F! H3 ]- | 第一种方式,在客户端管理用户的状态0 a/ m. H/ r0 q% S8 _; t3 q9 f
(cookie)。) M2 O* ^1 g8 q4 Y4 }
第二种方式,在服务器端管理用户的状态
8 P: s2 E9 S0 q" [7 C2 ?6 M& [( V (session)。
( b5 Z4 c W$ l! C7 G# ^9 z 3)cookie1 Z- g- Y {# ], q, F
a,什么是cookie? H! H g' ] _: y+ }
浏览器在访问服务器时,服务器将一些数据1 p3 }: t3 P T" G: o# g: w
以set-cookie消息头的形式发送给浏览器。浏览
' @3 ~: a7 C% m# B" P# B# k0 x 器会将这些数据保存起来。当浏览器再次访问
$ G* O" h$ A. ~ 服务器时,会将这些数据以cookie消息头的形式
* I) ^% h+ f, o5 G% o" @4 c 发送给服务器。通过这种方式,可以管理用户的
+ O" g$ J4 W' ~6 g4 D# d; t 状态。% b( |/ p3 K/ K5 Y: g
b,怎样创建cookie?
% ^. a7 ~) u1 v$ J Cookie cookie = new Cookie(String name,+ g4 R' E* n) y; O- _, A2 l
String value);" r8 T$ @, R- X( {
response.addCookie(cookie);
/ H, w+ o I1 G c,查询cookie& s5 u' z; a' f- C
//如果没有cookie,则返回null。/ `+ K% y! } h( V
Cookie[] cookies = request.getCookies();1 H9 G' a3 L& J8 \0 n9 w! L8 Z
String name = cookie.getName();& C) F- w/ R: s
String value = cookie.getValue();1 Y* ^+ s7 ^% }1 |& x
d,cookie保存时的编码问题
. o& f1 A, o. y. o# y cookie的值只能是ascii字符,如果是中文,
! a4 a0 J) [( p" K6 B/ ? 需要将中文转换成ascii字符形式。% ?, Q7 R) P5 g1 q% |
可以使用URLEncoder.encode()方法和
" V3 n9 B& v4 R- J% a URLDecoder.decode()方法来进行这种转换。
; | P; Y3 y4 N! N e,cookie的保存时间
: q7 F/ u& D% f cookie.setMaxAge(int seconds);
2 E" x' H p/ @7 E seconds > 0:浏览器会将cookie以文件的方式* z: p4 t/ D" y: V y8 ~* d1 @
保存在硬盘上。在超过指定的时间以后,会删除+ w5 |4 z& O) b. Y$ [1 y
该文件。% u9 ^2 k: n9 Y% i) l! w3 P. s
seconds < 0:默认值,浏览器会将cookie保存
; v* T+ j( O6 h) C# {! K' h 在内存里面。只有当浏览器关闭之后,才会删除。
4 `9 ~+ N& V5 n! J1 q* H seconds = 0:删除。
( m' }8 M% @" h f,删除cookie
% g+ q( q3 E: r0 i" J# w- e 比如要删除一个name为"username"的cookie。
9 b7 \; E% ?1 q* `; U9 d1 S$ ? Cookie c = new Cookie("username","");% @$ i" m6 q- P
c.setMaxAge(0);
, a2 k3 J8 E4 s2 O! C response.addCookie(c);
+ N8 u% a) V R: {# o g,cookie的路径问题
, ]' O0 U4 b7 D/ i 浏览器在向服务器上的某个地址发送请求时,
' @1 }: `1 q7 o/ J( s 会先比较cookie的路径与向访问的路径(地址)是+ u2 u" F! v% |3 V
否匹配。只有匹配的cookie,才会发送。
/ ~2 I, r! I+ `' g cookie的路径可以通过
7 b- Z. ^; R/ ~# @ q4 y& |7 C4 W cookie.setPath(String path)方法来设置。8 I% u+ T. i& N
如果没有设置,则有一个缺省的路径,缺省的
8 q- G$ B8 Z# m9 R 路径是生成该cookie的组件的路径。
- A( I$ Z3 S0 A6 ` 比如: /appname/addCookie保存了一个cookie,, l. C: _: Z9 u" D6 x; b4 V' }8 M4 Q
则该cookie的路径就是/appname/addCookie。0 G; ]! a1 ~5 |) H7 n+ K
, `- ~! Y: |- E 规则:; {( p1 i% z0 y
cookie的路径必须是要访问的路径的上层目录
" N) K8 l" b/ d4 b, R/ u 或者是与要访问的路径相等,浏览器才会
: C0 U% a. o6 t, C% f' s D 将cookie发送给服务器。
* ^2 n. D$ u9 |( E4 U' b
. W6 w* a0 o, K" @ 一般可以设置setPath("/appname"),表示访问1 l, K/ s+ p7 F4 i" B
该应用下的所有地址,均会发送cookie。
, G' D, W3 u; C* R6 I; V$ I h,cookie的限制1 m& r- R- Y# s% W
cookie可以禁止( ?, U0 o( \+ W, d5 p
cookie的大小有限制(4k左右)% @) M+ C* t. z+ y
cookie的数量也有限制(浏览器大约能保存300个) 5 I: h$ S. k" q0 s8 n+ k+ g
cookie的值只能是字符串,要考虑编码问题。
+ c, R8 @" N+ `/ L0 P cookie不安全
: E7 L5 Y0 i, Q; Z/ C% h 练习:5 }1 }0 Y0 }" N4 D: F- A2 u
写一个Add_FindCookieServlet,该servlet先查询
- {. F$ r5 i4 Z7 X) I 有没有一个名叫name的cookie,如果有,则显示
% C/ l( C x# i2 Q( D" J 该cookie的值,如果没有,则创建该cookie(
, j6 `1 F: J+ f+ U* C% v8 b; F cookie的名字:name,cookie的值:zs)。
3 y% |( P6 i) ]: D' U
" X- x' G1 m( `, ^3 {. \* Z. I
: @9 y" p6 m# w3 C7 } 4)session
( W( K( }6 D J& Y7 y; i. X a,什么是session?0 d" c& x9 F0 G
浏览器访问服务器时,服务器会创建一个session
# l4 O* s+ u* ]( O. d 对象(该对象有一个唯一的id, 一般称为sessionId)8 e8 e5 l% p( l3 S0 `3 O
。服务器在缺省情况下,会将sessionId以cookie
3 O3 k0 u" D* C3 M 机制发送给浏览器。当浏览器再次访问服务器时,
* T5 `# w' E5 u1 t' u6 }& k- G" B' r 会将sessionId发送给服务器。服务器依据sessionId
2 M% V. b8 i6 ^) h4 q: t 就可以找到对应的session对象。通过这种方式,4 z8 M1 e( s. Y2 _
就可以管理用户的状态。 `* F' H9 S( V/ S! {/ a
b,如何获得session对象9 u( M* h9 E1 a0 `7 H
方式一:
* X. p# `' ~4 M7 U) J HttpSession session = & Y3 R$ A; p# w4 N- Q
request.getSession(boolean flag);2 C. T! F0 ?1 R3 a( P" H
当flag = true:' O& q# P) g; U" Z! x) v! X4 F1 g
服务器会先查看请求中是否包含sessionId,
$ t) p4 x, N' h% H: @ 如果没有,则创建一个session对象。( m1 K1 z' o A* N
如果有,则依据sessionId去查找对应的
* p6 I3 j* _1 o+ Y' f session对象,如果找到,则返回。: |' U, O4 Q; j
如果找不到,则创建一个新的session对象。
0 E" C0 K$ a# i" Y( ^/ v# s 当flag = false:
/ z, S1 q! c/ W# k) j 服务器会先查看请求中是否包含sessionId,) p: Y6 O& M) z S( i& G1 G
如果没有,返回null。
7 i1 u' J$ V, j: ?2 K% d 如果有,则依据sessionId去查找对应的
4 O+ ?# I9 _+ e5 y& \8 T+ Q0 Z session对象,如果找到,则返回。
8 _, Q7 A1 j i+ Q$ H' k6 f 如果找不到,返回null。- W( o" k$ J5 i
方式二:+ h f5 B5 ^: `- i6 A
HttpSession session =
* S: u B+ c& i& T request.getSession();# Y+ L( `' H5 X( {! j0 w2 K% r
与request.getSession(true)等价。
! g. j A3 b% X5 |% `$ E; Y c,HttpSession接口提供的一些方法( |5 {9 H1 `" `9 S. y5 D* x
//获得sessionId。 l, R6 d. j5 r& J
String session.getId();% ?0 _2 N2 T( s4 w. f
//绑订数据
* W- ?6 H- B* }: G _ session.setAttribute(& v- B( c; r' e6 F7 {
String name,Object obj);) {4 t) y" q/ \6 a
//obj最好实现Serializable接口(服务器2 `& l5 p W2 w, O1 R& g4 h
在对session进行持久化操作时,比如钝化# o5 v8 ]5 w. u& \; A: B
、激活,会使用序列化协议)。
5 I0 Y& E" i3 A l2 } Object session.getAttribute(String name);
W; R& R5 o; C } //如果name对应的值不存在,返回null。
1 G) z. H7 D) t& u8 `& ? session.removeAttribute(String name);5 Q+ K* R4 Z1 L/ X+ E |
d,session超时( D1 j. Q! @: G; H# j7 D2 p7 p' V1 Y
服务器会将超过指定时间的session对象* E& X5 Q) c5 P
删除(在指定的时间内,该session对象没有. O8 k+ X Q6 F( B, c+ N8 X9 V# r
使用)。' K6 H2 s( V, k% ~ q- N& O
方式一:
' V) r1 Q2 J8 B+ g3 L session.setMaxInactiveInterval(3 _3 z2 N0 D7 [% X# X" _3 s9 X3 E
int seconds);% C: x4 j( h/ k" K& w
方式二:$ }4 N7 @0 A/ R# J
服务器有一个缺省的超时限制,可以
9 C' c# x( K: h3 z 通过相应的配置文件来重新设置。; b k0 `: P+ K1 E
比如可以修改tomcat的web.xml(3 O9 J9 }; G8 n. D0 T/ `
tomcat_home/conf下面)。
$ ~1 E/ z+ N+ k/ q <session-config>/ e, n" u, v5 B* v6 S8 @
<session-timeout>30</session-timeout>5 W5 r$ j3 _# P$ ^0 e
</session-config>
6 q3 r% L s& g, o( s 另外,也可以只修改某个应用的web.xml。7 Q$ W4 Q" G; @
e,删除session
, ~) z+ R4 j8 s( K0 B% Z1 O session.invalidate();+ r5 U+ V: t0 y
% [$ B6 j: O9 u
案例:- G K7 N9 K, ~4 x! g7 j
session验证$ Y1 b1 e, m- K/ i5 w- K
step1 在登录成功之后,在session上绑订一些数据。
+ B$ z* L8 \/ `, p3 D2 Z 比如:% m+ c+ R* G0 }3 J
session.setAttribute("user",user);0 z- O6 a" }& @- ? H# M3 h
step2 在访问需要保护的页面或者资源时,执行
& h! Z, t' A3 N5 e* z" u Object obj = session.getAttribute("user");
8 W! b) t' }1 U, a4 D: | 如果obj为null,说明没有登录,一般重定向到
. r- Q% c. Q! A4 M: n r# J# t 登录页面。
$ I' q3 x5 [4 @( L1 e |
-
总评分: 帮币 + 5
查看全部评分
|