该用户从未签到
|
2、状态管理! r& }8 \9 I- R: Y% h8 {
1)什么是状态管理9 m9 D% d) e2 U5 G7 I! S6 f
将客户端(一般是浏览器)与服务器之间的多次9 h# T# c& l2 _( Y) Y0 d$ M1 @
交互当作一个整体来看待,即将多次操作所涉及的/ r# n* r! F! a% j
数据记录下来。" j# T0 H8 \' \- z8 U- @% l7 `
2)怎样进行状态管理. K6 T2 W2 y* F4 s4 h& d: i
第一种方式,在客户端管理用户的状态
4 |9 s7 T/ e4 }- o (cookie)。
3 F! S9 |# o# Y/ u5 A 第二种方式,在服务器端管理用户的状态5 R. n! \. A3 ^# x2 l/ K+ ]
(session)。
- @2 }1 E& q) ?' f( l/ N 3)cookie: @! G% F- W' }$ P& H. ?: |
a,什么是cookie?2 D$ b* U" S$ E/ N2 V
浏览器在访问服务器时,服务器将一些数据
# Q# J. y2 v) r/ h$ n$ q- u) j 以set-cookie消息头的形式发送给浏览器。浏览
" F: W. H& G; U! ]4 _ 器会将这些数据保存起来。当浏览器再次访问$ H/ W% b6 y' C
服务器时,会将这些数据以cookie消息头的形式
! S1 G' s3 }' r2 s0 p' _3 q 发送给服务器。通过这种方式,可以管理用户的
7 W$ X1 x1 c6 K) J& w7 h: ?7 u8 }' F+ b 状态。 Y( @1 k. ]% i0 v9 v/ ]; R7 y/ H7 Z
b,怎样创建cookie?" e* i7 ~; I2 B {; H" X
Cookie cookie = new Cookie(String name,& |% b R# V; Z% y
String value);9 z l0 O% {9 j# l9 R; M T8 `
response.addCookie(cookie);
# P; Y# q- }3 ^. A- i4 d' H, X' @+ H c,查询cookie& I$ C, b! V' Z) B* x
//如果没有cookie,则返回null。7 B! u* S) I' o/ p, o( O
Cookie[] cookies = request.getCookies();2 O F$ d& b1 j1 \* c
String name = cookie.getName();0 M. X. R9 M( j
String value = cookie.getValue();
( j4 f, N6 L! D2 f" c0 F d,cookie保存时的编码问题, I) M* u/ v9 L& ~
cookie的值只能是ascii字符,如果是中文,6 e$ T( [# D" p+ t
需要将中文转换成ascii字符形式。
V5 \$ s6 _8 ?) ?: @ 可以使用URLEncoder.encode()方法和
# \; V. v5 z8 s& q5 ` s2 W/ C e/ w0 M0 m URLDecoder.decode()方法来进行这种转换。: F8 v+ W- {4 T
e,cookie的保存时间: [" k* v: K \
cookie.setMaxAge(int seconds);6 a6 X/ V U3 t& K; `* t- c
seconds > 0:浏览器会将cookie以文件的方式
$ n+ g; h8 }) O* H# l" \ 保存在硬盘上。在超过指定的时间以后,会删除+ N$ @) ]$ a/ o0 y
该文件。/ S$ Z/ B& w+ `) a) |
seconds < 0:默认值,浏览器会将cookie保存
3 H K. [3 c& m% N& n 在内存里面。只有当浏览器关闭之后,才会删除。( C6 h0 K, f) z. o, ~
seconds = 0:删除。
; a' N: z1 |/ ^0 A. V( o f,删除cookie' c! p5 V# t# f
比如要删除一个name为"username"的cookie。
/ R$ U$ y/ l( [: q' m, [* k Cookie c = new Cookie("username","");
- w" M" R) z* }4 F c.setMaxAge(0);, _2 o; Z' p, Q k; T" u8 u
response.addCookie(c);
! ?! D" E, T f5 ] g,cookie的路径问题
0 b/ m1 P1 x0 a2 R9 T( x 浏览器在向服务器上的某个地址发送请求时,
3 U5 H* m( b$ l" t+ R 会先比较cookie的路径与向访问的路径(地址)是. T2 x* X! k. x6 d- _! \0 X
否匹配。只有匹配的cookie,才会发送。; i! X3 U: M4 p$ n& k
cookie的路径可以通过4 ?6 {; q6 D' r3 h2 Y C0 V
cookie.setPath(String path)方法来设置。
1 ], V: g: Y5 Z 如果没有设置,则有一个缺省的路径,缺省的
: R4 y/ v# v2 a7 ~3 ?5 @, B 路径是生成该cookie的组件的路径。7 j0 u0 h; T$ Y1 O
比如: /appname/addCookie保存了一个cookie,
. \0 v# m* A- Z9 }& F# P, n$ u 则该cookie的路径就是/appname/addCookie。
- Y: |/ t$ q7 S4 h Q
/ d, H( i6 E9 [. \* G4 K 规则:: r2 C5 ~1 v% c. c( E; q' C+ l
cookie的路径必须是要访问的路径的上层目录. K6 `" p' y _
或者是与要访问的路径相等,浏览器才会4 x2 S2 R- S- M+ L2 S9 p) J
将cookie发送给服务器。9 j4 R& X8 B8 X0 v
i7 j! ], G9 g7 B 一般可以设置setPath("/appname"),表示访问
! h; v4 y* b8 V9 K7 {5 ^. j1 t 该应用下的所有地址,均会发送cookie。
9 W( N5 {% U- K v& } h,cookie的限制
) I4 |6 s1 P; g" k6 H cookie可以禁止
# ~/ l, u4 a; L$ l cookie的大小有限制(4k左右)
6 t! b7 _- h& X2 k, | cookie的数量也有限制(浏览器大约能保存300个) . L7 J! _1 O$ X9 X$ b {; u
cookie的值只能是字符串,要考虑编码问题。
* `' Z9 N) I% ~6 @# c7 h6 T cookie不安全- y3 a2 R/ x4 _# B$ d0 z- M
练习:
! Y) ]! ^9 a( n* ?$ `+ \* D 写一个Add_FindCookieServlet,该servlet先查询* \/ ^6 N' X4 A% ]2 w) W v
有没有一个名叫name的cookie,如果有,则显示: L& u" [9 [: N
该cookie的值,如果没有,则创建该cookie(
, S, }8 L6 e9 N# J# b2 W cookie的名字:name,cookie的值:zs)。4 }4 L j: i/ a1 i. y3 i9 Z, z
! \; }& x( O+ M+ v: o # E; ^2 M; j' w) }! L# l4 w
4)session
+ O3 O+ w+ E9 r4 P& O1 A x a,什么是session?' @; N# G( h( U7 A6 a+ b
浏览器访问服务器时,服务器会创建一个session' _ |! W* N, r5 V) N
对象(该对象有一个唯一的id, 一般称为sessionId). w8 Y4 @8 X5 F
。服务器在缺省情况下,会将sessionId以cookie& z1 A* o/ F3 L! a- ~5 O
机制发送给浏览器。当浏览器再次访问服务器时,
" a( L( U& B7 c! G 会将sessionId发送给服务器。服务器依据sessionId+ l$ {, N/ i8 a
就可以找到对应的session对象。通过这种方式,7 o- ], v* _; i: M) U
就可以管理用户的状态。
7 J, U% g* j4 c9 O b,如何获得session对象8 X' ~& V- r7 o( f R2 T
方式一:' c6 k. }6 l2 @; w3 H
HttpSession session = : x1 `: ]/ q/ u6 _ B( g# B
request.getSession(boolean flag);
4 Y% f ^% ?* Y1 C+ s; u 当flag = true:. h( \9 n/ R" m; }
服务器会先查看请求中是否包含sessionId,
0 W4 n. E( @) _5 h, c 如果没有,则创建一个session对象。6 ^0 J' x/ h" j. y Q+ |8 Q! S4 |
如果有,则依据sessionId去查找对应的
( z: ?. \- q# ?$ L3 U- R/ v8 d8 \6 p session对象,如果找到,则返回。
* `7 z9 X' Q x0 o, Y: }3 L 如果找不到,则创建一个新的session对象。
" ~9 g+ p* A0 {2 z 当flag = false:
9 J6 b! `' ?; E- _1 ~; v: ~ 服务器会先查看请求中是否包含sessionId,& a! M' e0 a* L/ R6 O0 L/ T
如果没有,返回null。3 \2 b+ y) L4 `9 M$ X* D. A
如果有,则依据sessionId去查找对应的1 `) ?$ ~8 q5 [
session对象,如果找到,则返回。5 F; Y$ f/ z/ [. g& J* c7 z
如果找不到,返回null。# { ?. k$ i) [4 d' U! |
方式二:
( T: w( D* A5 t/ ?( c( \6 l# G HttpSession session = " U: m! ~1 o8 w2 [( x8 m0 p4 h
request.getSession();
1 g+ D, r# T) ~( H4 J3 d! K6 R 与request.getSession(true)等价。
: ~; d( p- z8 X: Z# {- w c,HttpSession接口提供的一些方法. U8 K, V) W7 \" i, D1 K( i
//获得sessionId。4 q5 l q6 c6 v- t
String session.getId();# p$ B5 s" l1 e& N2 e+ [
//绑订数据
0 Y5 w% u! p' u: R$ O& w session.setAttribute(
+ F7 k3 E+ o5 _7 O String name,Object obj);3 H1 o, V& ?6 d1 W/ d! n% u
//obj最好实现Serializable接口(服务器
, f6 J! p# y* J3 L$ T 在对session进行持久化操作时,比如钝化
. O' k' |- u9 Z0 \7 Y) ?# D q 、激活,会使用序列化协议)。4 I# `! o$ s L" J6 j7 t) U. m
Object session.getAttribute(String name);
- k7 @7 b0 D, s6 b; e* G% U //如果name对应的值不存在,返回null。
( m/ ~$ W4 c' D1 b6 b. N0 L" F/ u1 K session.removeAttribute(String name);
5 ]7 \8 _% |% p0 X6 W d,session超时
, e4 Y' V, T1 Z5 t 服务器会将超过指定时间的session对象; {$ G, Y0 o0 [ N9 _
删除(在指定的时间内,该session对象没有4 t0 r# h; S8 {4 Z6 ?. s, N
使用)。0 P& m5 E* y) c8 {, x: {
方式一:
* j1 ~/ t3 g: }& k C session.setMaxInactiveInterval(
1 C" ~, v [- Q8 a! A int seconds);
& F1 H1 z }! l- n4 |/ e" { 方式二:
( |% ^7 T, ^8 d8 \* p 服务器有一个缺省的超时限制,可以
0 [2 j8 E e& t2 e 通过相应的配置文件来重新设置。$ I7 N# a% y. W( z/ |0 I3 }! y
比如可以修改tomcat的web.xml() `! K+ D8 m- ?% U- ^5 `
tomcat_home/conf下面)。% @3 |# O* a8 p( ]1 H1 Q% W
<session-config>$ _% C0 k4 J: S( P# o9 F* A
<session-timeout>30</session-timeout>' v+ t5 J3 H* U7 R! i! ^% }) b
</session-config>5 K. p/ O `9 }: Q
另外,也可以只修改某个应用的web.xml。
8 g, p- X! ^, O) ~* D e,删除session$ T- p1 \: V& [! L: h- m
session.invalidate();- z6 g; r: b5 [" `
& T' E2 _) P: \ 案例:
# R: ~' F" ?8 U f ` session验证# }! H* i! M Z+ ]2 ?" P2 ~
step1 在登录成功之后,在session上绑订一些数据。
, E3 p. {" y2 p2 x: X7 ~$ k8 S6 p 比如:' a4 ~, J! t. X) F: _
session.setAttribute("user",user);
+ T( K) F8 t8 R# @/ V( e0 s# |: ] step2 在访问需要保护的页面或者资源时,执行& `0 @: t3 K, B: N7 @/ v$ m
Object obj = session.getAttribute("user");
! W4 b* Z; K- D- Y 如果obj为null,说明没有登录,一般重定向到9 z$ K, h2 g. a7 N
登录页面。
' A" v8 |4 v) ~ a1 i |
-
总评分: 帮币 + 5
查看全部评分
|