|
该用户从未签到
|
2、状态管理" m% A6 i! ~0 ~' i' u6 Y
1)什么是状态管理( O+ Q6 O( v7 F: R' T& u+ m) f
将客户端(一般是浏览器)与服务器之间的多次
! C4 |& k- n% G 交互当作一个整体来看待,即将多次操作所涉及的! O5 Q c; v, [, J+ M/ a4 I7 U
数据记录下来。
- l9 a# g1 ]1 v9 H6 D/ a" I0 Y- F1 N 2)怎样进行状态管理
( P; B! K4 `* t0 e3 ] 第一种方式,在客户端管理用户的状态
}0 | W0 W6 b. z1 {: T% v (cookie)。
# H5 Z7 g2 }4 x9 W 第二种方式,在服务器端管理用户的状态/ F& b( x8 o4 h ~
(session)。7 S- [+ b7 ^% ]8 T) v
3)cookie
8 N$ A1 ]! Z J) t1 R$ j a,什么是cookie?3 w( }: C' h7 [/ u& d( N
浏览器在访问服务器时,服务器将一些数据& V3 ^5 S/ U- c
以set-cookie消息头的形式发送给浏览器。浏览
; w' [6 a/ | u# u0 ` 器会将这些数据保存起来。当浏览器再次访问
& [" r, k% E4 ~2 K 服务器时,会将这些数据以cookie消息头的形式
" b, {! b" p( z0 X' a* y w/ I 发送给服务器。通过这种方式,可以管理用户的
, L) B2 m5 q/ M 状态。/ j& E! ]9 P3 v/ W
b,怎样创建cookie?: r8 ]! }' Q( f
Cookie cookie = new Cookie(String name,- _3 `4 F3 W8 [3 n/ N* E/ e7 Q7 x
String value);, ?/ _# _% g" ]: h
response.addCookie(cookie);
3 i+ w) }* b) S: ?' m: z c,查询cookie
' F: x4 V5 G; x/ o //如果没有cookie,则返回null。
# I. R; g2 \7 e6 d- r4 u+ U Cookie[] cookies = request.getCookies();
$ F h. s/ L- {: N( L0 P$ k% h4 N String name = cookie.getName();. \3 z( s0 U6 D- [- X; ~' c0 ^& w
String value = cookie.getValue();
6 h9 U/ W! ~- ]8 ?/ a) o d,cookie保存时的编码问题+ x) G* ~/ q: r' f5 J1 O% g" W
cookie的值只能是ascii字符,如果是中文,
( ?" s0 i; V% m1 Z5 M8 w$ f 需要将中文转换成ascii字符形式。$ u3 } I8 w# I! ^/ l! @( @, B' H, Y9 M% A
可以使用URLEncoder.encode()方法和0 k O3 r% {) \; [) w8 I$ S
URLDecoder.decode()方法来进行这种转换。
; G) _6 ~. g9 H& k( ~8 I2 a( A e,cookie的保存时间
% k. s h. _! r( n cookie.setMaxAge(int seconds);
" K, _7 c) Z% v seconds > 0:浏览器会将cookie以文件的方式1 M: @# Z8 @6 Y' D% @% N
保存在硬盘上。在超过指定的时间以后,会删除
: V0 V. l5 J) o$ R$ d* d% t 该文件。
2 Q' t0 Q* \% P% w, h6 U seconds < 0:默认值,浏览器会将cookie保存
3 }/ @6 |; B0 b3 ?) Q 在内存里面。只有当浏览器关闭之后,才会删除。- p3 V; Y* z; H- ]# ?' i G3 W. A2 `
seconds = 0:删除。3 r# o9 S3 E7 t6 O/ W) c+ [5 w0 G9 B
f,删除cookie+ H8 T6 m* v& ~$ c: Z; F
比如要删除一个name为"username"的cookie。
( ~; D" k5 ]# i. s6 M Cookie c = new Cookie("username","");
! u1 |7 `9 c# P c.setMaxAge(0);% y1 f* z1 V# f# ~8 |
response.addCookie(c);1 ?0 `+ f( W6 d* I; b
g,cookie的路径问题; `0 a# O h+ W% @& b
浏览器在向服务器上的某个地址发送请求时,
4 O5 ^( B( c- x! |2 D' P$ z0 ? 会先比较cookie的路径与向访问的路径(地址)是
- L6 o: I; q- }* c2 i& c& ] 否匹配。只有匹配的cookie,才会发送。" A3 W) ], i* [# o$ Z, [2 }- P1 y
cookie的路径可以通过
( N& V+ `- I3 ~: O8 l: M5 Q5 k cookie.setPath(String path)方法来设置。
' f: R1 v+ l( T, ~) f 如果没有设置,则有一个缺省的路径,缺省的7 V% f# u1 N6 A% L: ?' Y
路径是生成该cookie的组件的路径。' A" y0 I4 d6 j1 g( u, A. O) C( G- U
比如: /appname/addCookie保存了一个cookie,
/ }0 ?- O# Z& q7 o# O5 }) F 则该cookie的路径就是/appname/addCookie。! |3 K% N1 H2 y) G, b
* w! N" d- ?4 y& p4 }7 ?3 x9 l
规则:
( T& V) J* A" |1 P- t0 Y$ o$ @7 z cookie的路径必须是要访问的路径的上层目录
4 M _9 x# y( b [1 B L: Q; ^ 或者是与要访问的路径相等,浏览器才会' t9 n, v" G8 ^. S/ U
将cookie发送给服务器。) }; @4 \4 |- S0 ?* A x5 \
4 f. l4 c: w. r4 h
一般可以设置setPath("/appname"),表示访问
$ M; S+ {% D3 ~6 c4 |7 |6 t! K3 r 该应用下的所有地址,均会发送cookie。
6 Y# d9 {1 e. Y+ ]! }" t1 v h,cookie的限制. S( ^( H% z- Y
cookie可以禁止9 d9 B# q8 o8 K0 g; r( a
cookie的大小有限制(4k左右)
( _+ h8 k7 Y. \( h+ z& v cookie的数量也有限制(浏览器大约能保存300个) ! E9 ~' c; u( X! H( B, }# `
cookie的值只能是字符串,要考虑编码问题。3 p% L( Q0 {5 C3 O4 c. d, X9 a
cookie不安全
, i5 U2 h0 w" ~ 练习:5 b7 a+ y+ v4 a% w# k
写一个Add_FindCookieServlet,该servlet先查询
& c& s7 L$ L7 { 有没有一个名叫name的cookie,如果有,则显示
7 [# Q4 L( }. |' L5 m- v/ z( D$ S: ^" d# ] 该cookie的值,如果没有,则创建该cookie(- \" Q2 J( q; p# I6 K4 T/ o" g
cookie的名字:name,cookie的值:zs)。
7 _7 E# H. U9 ^* b9 O) |. R# d R0 ?# K' J) ~; p2 [6 N, p
; t( o* e D- y6 v 4)session 5 [6 K! s {; t$ _3 n
a,什么是session?) f" p) T4 N% m6 U
浏览器访问服务器时,服务器会创建一个session
7 a, J" A7 I( T; }3 z, L 对象(该对象有一个唯一的id, 一般称为sessionId)
! I- ~2 n1 C9 e) P% z 。服务器在缺省情况下,会将sessionId以cookie' f+ Q( h# j# f1 O$ \3 i2 c
机制发送给浏览器。当浏览器再次访问服务器时,
$ B! ]2 ~( l2 f# ?# O 会将sessionId发送给服务器。服务器依据sessionId) |- s+ D! X1 L! y [- y8 R+ f
就可以找到对应的session对象。通过这种方式,, T$ U, \' x9 D7 ~' R
就可以管理用户的状态。
9 y: k# h9 }8 _% y. I. W: r- W b,如何获得session对象 P9 H% U/ Y! e' k5 C
方式一:
# Y$ G8 L) @. R% r% Y# { HttpSession session =
/ H. \5 }7 [% s# q0 ? request.getSession(boolean flag);: }) ^ U% y- ]
当flag = true:& c, @$ U. V* P4 E
服务器会先查看请求中是否包含sessionId,+ B/ m! [6 E2 O+ _
如果没有,则创建一个session对象。. c# o1 z1 ]' @
如果有,则依据sessionId去查找对应的2 b) ~- R4 X! y! n% T0 Q. w! O. {) ~
session对象,如果找到,则返回。
5 B; f3 e) f0 ^. [8 H+ Z- V 如果找不到,则创建一个新的session对象。
9 B4 G/ W: p7 K 当flag = false:
8 `- p* h7 z+ V: c" u* G 服务器会先查看请求中是否包含sessionId,
5 x; W8 w( q o$ R" R/ ^$ x 如果没有,返回null。
9 x* ]: O5 \1 \1 y7 n 如果有,则依据sessionId去查找对应的
8 H7 k8 Y' ^- s0 F session对象,如果找到,则返回。
9 l- y" [8 V9 `7 w8 p0 S9 a 如果找不到,返回null。. d* Z- i. S V, w2 D% H8 D
方式二:
/ [8 f8 a2 J' V0 Y$ W2 m HttpSession session =
0 v3 H9 A) c( X request.getSession();
0 D' @6 z* f) a 与request.getSession(true)等价。
^+ q7 i9 M0 @! E$ [ c,HttpSession接口提供的一些方法, }0 A" k% A$ q; s
//获得sessionId。9 W4 }) r) M8 _" D h o9 W- _& a$ n
String session.getId();. c& i3 g5 p0 w5 |: ]+ L! O: _5 U. F
//绑订数据
3 R+ B% P% ?/ |3 x F) m& e session.setAttribute(6 x* I0 Z9 B( l# Q
String name,Object obj);
) |7 k. v+ E$ D0 n0 A7 d1 o //obj最好实现Serializable接口(服务器0 ^" s8 ^" `" k4 X% [ O
在对session进行持久化操作时,比如钝化: @" f3 Q8 ~* q: E `
、激活,会使用序列化协议)。: H' r& ^3 w7 Z! l/ `' x
Object session.getAttribute(String name);
2 U2 J n9 ~, [' t+ Y A! ]" |" k //如果name对应的值不存在,返回null。
$ p/ s2 ]$ a% L# a2 M; A session.removeAttribute(String name);
% |( n9 c# Y0 C- a6 A7 y d,session超时
- e" J; [$ z. m5 A 服务器会将超过指定时间的session对象8 o" |; w/ r P [. \0 A
删除(在指定的时间内,该session对象没有
: v( R1 u3 {$ H! T" T- D 使用)。
0 B/ @1 n g: C" a: y, V 方式一:
5 k2 C3 n. [7 l+ Q g; I: r session.setMaxInactiveInterval( m$ Z4 i" k; l
int seconds);- u$ a9 S+ o7 j* b+ }/ f) w4 \
方式二:) d: N1 E- J0 F* z1 U; f6 s
服务器有一个缺省的超时限制,可以" V( ^& _* K% P* O
通过相应的配置文件来重新设置。
) `2 Z0 S0 o+ x% p 比如可以修改tomcat的web.xml(: j5 K# `: d. I' y _# ]) N
tomcat_home/conf下面)。8 g; ~0 D: }+ S, p, R: F0 ^: ~
<session-config>1 z) V" m3 s% N4 `+ U
<session-timeout>30</session-timeout>4 Q+ v- m' u: P- N
</session-config>. L) W( Z1 M4 o$ o2 d4 b
另外,也可以只修改某个应用的web.xml。
. {) c" Z9 g5 B6 B3 n! C e,删除session1 F1 @4 M+ U5 P4 Q/ }. t9 d
session.invalidate();9 I% N5 ]/ E' w+ a6 N" S
% M, T9 G- A5 f; j9 f 案例:
5 H& L [- p6 W4 A& Z/ O* z session验证 b1 ~. p8 ]$ r8 j7 [
step1 在登录成功之后,在session上绑订一些数据。
3 l$ N! `' }+ W& V; v8 g 比如:
% }1 e# x. A# w1 L7 X2 J session.setAttribute("user",user);3 C2 \0 u0 M" b6 `+ _
step2 在访问需要保护的页面或者资源时,执行
$ s" C2 x" F. x" y8 V( r Object obj = session.getAttribute("user");' x6 X. h7 h& D6 C
如果obj为null,说明没有登录,一般重定向到- q8 Z# G1 [" b1 a" {. H8 H
登录页面。
. `$ L) R b( [3 V$ f) b- C7 I |
-
总评分: 帮币 + 5
查看全部评分
|