|
该用户从未签到
|
2、状态管理0 h" G0 m# g% }* C
1)什么是状态管理 W5 N6 `! u1 c' E7 b& x+ c
将客户端(一般是浏览器)与服务器之间的多次
. {0 Y; Z. J. b) `$ ?/ t3 P V; T 交互当作一个整体来看待,即将多次操作所涉及的
; B' f; _+ N+ b) x( | 数据记录下来。
/ l4 W7 @ `2 }- k5 i 2)怎样进行状态管理- o0 M% e. U. d Q2 a
第一种方式,在客户端管理用户的状态
2 j4 X6 ~ y; W5 c7 y (cookie)。
% z0 ?, K4 S' J4 ^( r* r. x 第二种方式,在服务器端管理用户的状态
! h& H! [9 P7 p& L0 y (session)。
' D, r# S$ Y% h9 ^" E" [# U# T 3)cookie9 _4 G! o8 |! ?
a,什么是cookie?- G' y8 k6 l5 B0 r
浏览器在访问服务器时,服务器将一些数据7 d8 ]8 t/ l, X2 j, l+ {
以set-cookie消息头的形式发送给浏览器。浏览
, F1 |8 `% ], L( @& V4 d 器会将这些数据保存起来。当浏览器再次访问9 B8 g* N3 A$ Q9 Q! M6 Y K
服务器时,会将这些数据以cookie消息头的形式
% P2 U( A& w" }- h! D, f 发送给服务器。通过这种方式,可以管理用户的! [1 A8 ]- v" W7 l: ~) K6 V) @9 ?
状态。/ j( J; d$ P. G% n+ T
b,怎样创建cookie?$ i; i2 R6 ~- I5 _5 l
Cookie cookie = new Cookie(String name,, D3 m c( r" X7 Q6 P8 N
String value);5 {+ m& O$ @4 k9 s, u7 d
response.addCookie(cookie);
* D8 S6 T7 _, M. E2 T+ M c,查询cookie: C/ o. l2 N2 ?
//如果没有cookie,则返回null。
; ^8 E+ n) `, i* U Cookie[] cookies = request.getCookies();7 N, w0 j4 b4 K2 C+ b
String name = cookie.getName();
! y$ N/ B/ e$ y7 B- N4 r String value = cookie.getValue();; _! B9 e( g4 d3 Y/ D' T u% E' C8 k
d,cookie保存时的编码问题; |' D$ w5 g$ \' h! ?+ q) u
cookie的值只能是ascii字符,如果是中文,
7 h. C1 j, R' ` z5 ` 需要将中文转换成ascii字符形式。+ t3 _+ e# ?" T* C7 Y
可以使用URLEncoder.encode()方法和. _# F) o* M% d$ D
URLDecoder.decode()方法来进行这种转换。
9 F8 H! n6 x" J( f H% R e,cookie的保存时间
6 h/ `4 C% ], y, r. u9 q" T cookie.setMaxAge(int seconds);
- Q! I2 N7 i- F- c seconds > 0:浏览器会将cookie以文件的方式
8 @- A, K8 ]* V6 j8 U3 i 保存在硬盘上。在超过指定的时间以后,会删除
6 L: l/ I8 i0 k2 K 该文件。
) B- w5 [ x; Y/ @5 M8 V# V seconds < 0:默认值,浏览器会将cookie保存( N2 X y* F; P; N
在内存里面。只有当浏览器关闭之后,才会删除。
( x0 Y! K( M' f( ]+ K2 R2 D! h" [ seconds = 0:删除。
' a. V5 g( V7 g2 a f,删除cookie6 X* Q/ w& U+ v
比如要删除一个name为"username"的cookie。
, r$ ]" `4 R j- ~ Cookie c = new Cookie("username","");3 q: H; ^$ G% L; }6 r
c.setMaxAge(0);) s- K O/ G; }1 |
response.addCookie(c);
/ e2 u3 ~* _, O8 k; B8 }6 p: v9 Y g,cookie的路径问题" h$ M- ?5 K' h& i
浏览器在向服务器上的某个地址发送请求时,
; ?8 x1 n7 {& l! r1 ^ 会先比较cookie的路径与向访问的路径(地址)是( q0 h: D( b+ H3 b# |
否匹配。只有匹配的cookie,才会发送。4 T/ Z7 S% b* J
cookie的路径可以通过: R5 v+ W+ ^; E2 | ~! O# z( a% O
cookie.setPath(String path)方法来设置。
' Y! x% ~! R" p B3 O 如果没有设置,则有一个缺省的路径,缺省的: y8 V% j$ g- i2 Y- u5 ^
路径是生成该cookie的组件的路径。9 z2 u p9 f( | G+ P
比如: /appname/addCookie保存了一个cookie,4 ]6 H \5 @$ e3 g3 L: s& A
则该cookie的路径就是/appname/addCookie。& w' |3 \+ T2 s5 f) ]
. N$ _8 g2 k8 D- B6 z 规则:
1 I. v z3 h" X; G% t cookie的路径必须是要访问的路径的上层目录) e% d5 Z7 n; ]% U9 \4 j; p2 f1 w
或者是与要访问的路径相等,浏览器才会& l2 M/ e3 ?$ C, k: z$ ^+ i2 O
将cookie发送给服务器。1 M9 E; B( b6 ?# `, J# n
. Z" W: j' e, l5 _0 K+ ]. `
一般可以设置setPath("/appname"),表示访问
9 c5 g' L7 p9 c% O3 U# g f 该应用下的所有地址,均会发送cookie。- J' G$ q0 f; l1 M: a
h,cookie的限制
# H% Q5 z9 e4 Z/ u1 h: p5 B. y cookie可以禁止
+ T+ I- t- g$ E- i7 R1 K( m cookie的大小有限制(4k左右)
/ w6 ~& }6 ]7 h0 M/ Q+ h! y# D cookie的数量也有限制(浏览器大约能保存300个)
4 b$ J8 I) p3 o/ T1 f cookie的值只能是字符串,要考虑编码问题。$ M/ y! C' h, H1 ?- A! W
cookie不安全
2 u: O( j- L% A. p" d$ r/ m 练习:+ t+ T) A) x& j7 ^" E2 V" `1 n2 l
写一个Add_FindCookieServlet,该servlet先查询/ V4 ?$ y- n2 E. m
有没有一个名叫name的cookie,如果有,则显示7 c- C& c+ ]9 s
该cookie的值,如果没有,则创建该cookie(8 A: @% s- d5 j# t( \0 J
cookie的名字:name,cookie的值:zs)。
' {4 E# D& I. x1 l3 N. q4 | , |5 L; w: x, R* C& F
) i8 D7 O5 ~: E; {$ a+ X
4)session 2 E% ?) |7 O g+ _2 N
a,什么是session?+ H! k9 u* t# [' ^ L/ D: M) i* I
浏览器访问服务器时,服务器会创建一个session
9 Y1 g0 F: B5 U 对象(该对象有一个唯一的id, 一般称为sessionId)
6 S4 Y$ T6 i! _" e( k 。服务器在缺省情况下,会将sessionId以cookie# \( y, L% u2 c' k' k
机制发送给浏览器。当浏览器再次访问服务器时,
1 [6 D" f- N6 G4 C- i* I; g6 U5 B 会将sessionId发送给服务器。服务器依据sessionId
' y: Z+ B$ E2 h* E2 ~3 e 就可以找到对应的session对象。通过这种方式," B7 a. k* q4 p/ `( P k$ y0 b
就可以管理用户的状态。
1 b0 _$ e8 t+ g- A' G) z1 m3 ~! B b,如何获得session对象# m7 _/ Q9 S5 Q/ E0 `
方式一:8 o7 P4 Q* B5 p) M. E" P$ j* {2 [
HttpSession session =
7 J. y. ]5 O3 }; ?( r, y& S request.getSession(boolean flag);4 ?) t) q4 L( V
当flag = true:
8 I: ~5 R* g/ G: Y2 N 服务器会先查看请求中是否包含sessionId,
c; ^1 I5 I7 u, L" s1 V5 k+ \2 H 如果没有,则创建一个session对象。) P# @& M- J) m% S V+ n: w2 t
如果有,则依据sessionId去查找对应的4 S J/ d+ K& N6 z7 w' G
session对象,如果找到,则返回。
$ E: q R0 j# B. ? 如果找不到,则创建一个新的session对象。 g- P* q7 z- U% k% U0 U2 P
当flag = false:
1 i9 H* g L. j4 i: T2 C- a4 J 服务器会先查看请求中是否包含sessionId,- {3 P8 x0 G0 x1 C
如果没有,返回null。
2 b( S8 i% M4 E0 L, i7 a 如果有,则依据sessionId去查找对应的
9 z( c4 a2 |. P5 K- k( s session对象,如果找到,则返回。
+ g% V" D; {: B# M+ E% c# o 如果找不到,返回null。6 l+ W; E! m0 \% S3 x: i: F
方式二: P* J N+ t( N9 g
HttpSession session =
1 `% G0 u! {2 y) N% ~; T request.getSession();
7 q7 K E, y: S7 l6 h# E 与request.getSession(true)等价。
- r; V1 g$ p8 o- R c,HttpSession接口提供的一些方法0 w5 g/ _/ H; c1 S
//获得sessionId。
' O( h! m/ F( L! ? String session.getId();/ s8 v# M* ~8 p3 R$ S" y
//绑订数据
c; l; }# q5 [: Z) O session.setAttribute(
7 @7 n. J" K5 V3 N String name,Object obj);
8 s3 k' _. A) Q //obj最好实现Serializable接口(服务器
7 U7 n0 S6 R$ ?7 d+ S 在对session进行持久化操作时,比如钝化; V; h! ~: Z3 e# W! D( T7 ~1 v7 K
、激活,会使用序列化协议)。# S$ H2 R% T( A" K" C# T3 u4 j! J
Object session.getAttribute(String name);
2 w* B' o. [, ? W( K+ u //如果name对应的值不存在,返回null。
0 U* z5 \* f: e) ~ session.removeAttribute(String name);
; f5 L) o- D w& C9 ^: R+ P d,session超时
) z1 Z' F8 W M) L! c+ R 服务器会将超过指定时间的session对象1 p% r/ ~: @3 h
删除(在指定的时间内,该session对象没有
0 F; i) q# w" ]2 W+ e 使用)。: d; V3 ~! v) Q# t R; i$ J& R
方式一:; q' w; t" f5 ^
session.setMaxInactiveInterval(
; M0 ~6 g+ t& Q. G* n$ \/ B- W4 V0 o int seconds);
, g! B6 x: ^5 Z! e7 C B; @ 方式二:+ O" S" L/ n3 p9 ^1 @! D G
服务器有一个缺省的超时限制,可以
6 L8 O' A% S# T! T+ S9 Y 通过相应的配置文件来重新设置。
- c1 d* Z# S0 T% S1 {6 P" h5 |4 V 比如可以修改tomcat的web.xml() s! {0 ~7 G" q
tomcat_home/conf下面)。
2 O9 u) ^4 e A! J+ { Q <session-config>
: ]: B9 X( a) Z1 w* ]+ R5 C <session-timeout>30</session-timeout>4 O9 H( j' w8 f/ Z' S k! O
</session-config> x/ h8 z: d. Y6 L T# v
另外,也可以只修改某个应用的web.xml。
+ `1 ^# ?( |: \ e,删除session3 x! r9 h& q: T9 l/ m
session.invalidate();/ A9 I) R4 h1 _0 \
8 y' X" U* k3 ]% |
案例:
3 e3 `5 x& E) |( k session验证
8 @* Z' d: E/ O7 E step1 在登录成功之后,在session上绑订一些数据。
8 K' `! X/ d1 G0 L) n 比如:3 v3 ~( ^) O: o/ h* [: r
session.setAttribute("user",user); I4 M4 l8 ?* r( W& D
step2 在访问需要保护的页面或者资源时,执行
% {. t2 ^/ U4 ]/ Z! D Object obj = session.getAttribute("user");4 f8 z" C, f' t
如果obj为null,说明没有登录,一般重定向到
" D D# G2 h2 _& _& U 登录页面。6 a4 y' T' T2 U9 l
|
-
总评分: 帮币 + 5
查看全部评分
|