该用户从未签到
|
2、状态管理
3 G) v$ c6 @: ~" C# j 1)什么是状态管理: j7 a4 s& Z! h1 Y9 o
将客户端(一般是浏览器)与服务器之间的多次" }/ m t) o1 l0 Q
交互当作一个整体来看待,即将多次操作所涉及的
3 G+ t& b# X5 R# N. D$ w/ h 数据记录下来。# d) c/ a5 h* n) h4 {
2)怎样进行状态管理, F Y/ x; x) p
第一种方式,在客户端管理用户的状态
a+ J* s6 E% B8 g$ n8 Z! q: X (cookie)。
. d0 w5 \4 N. j& N r 第二种方式,在服务器端管理用户的状态
1 e2 c7 x, d$ K4 G4 l! ] (session)。
& L5 e% C$ V- q 3)cookie
0 i% ^9 R _2 k; L a,什么是cookie?
t: t6 @2 V: t8 N& ~- L( B 浏览器在访问服务器时,服务器将一些数据
/ }: U1 W! U* b3 K0 @& S" b 以set-cookie消息头的形式发送给浏览器。浏览! f: j! O* B" a/ _
器会将这些数据保存起来。当浏览器再次访问
: V$ r/ [7 M6 b; a0 m5 X 服务器时,会将这些数据以cookie消息头的形式* C# L! ^( y- W
发送给服务器。通过这种方式,可以管理用户的- ?* _4 ^4 E9 X/ h; |
状态。7 Z2 ?+ |6 w" r( N! f7 k) J% R
b,怎样创建cookie?
; ?; u* o- t, W1 G4 Q Cookie cookie = new Cookie(String name,
1 ]8 j" v. I" U' V# H String value);1 B$ m8 P/ r0 m& q
response.addCookie(cookie);
9 G3 V* r# L" _* r c,查询cookie( v9 E$ X! D) P* `. b
//如果没有cookie,则返回null。) E3 f# ?! x* t$ w+ A$ P- I" v% e
Cookie[] cookies = request.getCookies();
( t8 @) S! V1 Z% s# g String name = cookie.getName();
+ D! Z2 C3 B- } String value = cookie.getValue();
* _7 {. K8 C. O Q: | d,cookie保存时的编码问题 V- a7 e5 @$ t l
cookie的值只能是ascii字符,如果是中文,6 o4 I) @1 h Y" L
需要将中文转换成ascii字符形式。/ Q/ _0 G; Y0 A% w0 X5 ?2 j$ @
可以使用URLEncoder.encode()方法和
# n3 H# Z9 [( A3 V- F, a URLDecoder.decode()方法来进行这种转换。9 B4 j9 ?# p& m8 q8 }' Z
e,cookie的保存时间
( F0 l. X9 {& }7 @! X cookie.setMaxAge(int seconds);
8 g+ B. t h# E' t$ @, i& h) [& o seconds > 0:浏览器会将cookie以文件的方式( p X3 O5 e" S8 y, x3 P+ d
保存在硬盘上。在超过指定的时间以后,会删除6 f' u. k. H& x+ V$ `
该文件。2 D3 i" J. Y5 D$ a! a
seconds < 0:默认值,浏览器会将cookie保存/ O, Y0 B/ H3 A: l: B) j' ]
在内存里面。只有当浏览器关闭之后,才会删除。
, a( a" I& }$ x9 k seconds = 0:删除。
; S' V( v6 y( y2 ^2 B7 m6 {8 I f,删除cookie! v, g* I1 ? d i/ n' [1 a9 N8 o1 E
比如要删除一个name为"username"的cookie。
& b; L' X7 r3 J, A' p: R7 p$ x' z$ ^ Cookie c = new Cookie("username","");& J3 d/ O+ I( h; |) b
c.setMaxAge(0);
. q; D3 X7 }' i( u response.addCookie(c);
* ~3 T' A6 x2 ~( p F t; h g,cookie的路径问题; F2 ]8 c; p) Q7 F% A. k
浏览器在向服务器上的某个地址发送请求时,
/ t& p) I) E& `" p' h' d 会先比较cookie的路径与向访问的路径(地址)是
9 g0 Z7 b% M+ T' O( s 否匹配。只有匹配的cookie,才会发送。
$ z2 n: p! c# D5 J cookie的路径可以通过7 W. X0 i* G O; c
cookie.setPath(String path)方法来设置。! }& r" E! f# k& [4 [- [
如果没有设置,则有一个缺省的路径,缺省的
2 d, C( I" ~6 u$ k. S7 R/ Y- p 路径是生成该cookie的组件的路径。8 F) g7 ?- k8 R' C+ {5 F
比如: /appname/addCookie保存了一个cookie,
: Q& E$ Y4 }& I9 ~+ t* W 则该cookie的路径就是/appname/addCookie。
, \' S# ?! R, P9 v
: }0 I2 j) k8 b5 e) w 规则:
. D# s6 S! G7 N6 I' r cookie的路径必须是要访问的路径的上层目录9 `% E/ s9 `% ?" |8 d- u1 F& J
或者是与要访问的路径相等,浏览器才会- _& ^1 o* B4 @* u( D) }) h/ I
将cookie发送给服务器。
2 H. B. `7 R( U, Y/ v0 d, E / Q. N/ l5 R4 S" b/ u4 j
一般可以设置setPath("/appname"),表示访问& A* R; T4 k3 P" L+ a+ ^
该应用下的所有地址,均会发送cookie。
. n9 c! _% e" P0 A* E9 a2 S3 l& l h,cookie的限制
6 e/ H8 P* n3 X* V# M cookie可以禁止
- W' V. o: m" \9 j/ `& J cookie的大小有限制(4k左右)) G8 G# K5 S1 ?5 q T, h7 q
cookie的数量也有限制(浏览器大约能保存300个) 5 X$ }. v# `+ }2 ?
cookie的值只能是字符串,要考虑编码问题。
: |7 Z0 ~, e9 E cookie不安全7 I0 m4 E9 t5 x
练习:3 e* T4 J) |1 s
写一个Add_FindCookieServlet,该servlet先查询
4 P U# q$ w* I8 } 有没有一个名叫name的cookie,如果有,则显示6 }1 ]0 S I' m3 X& W0 j
该cookie的值,如果没有,则创建该cookie(6 k9 ]" W$ R0 O1 [5 p
cookie的名字:name,cookie的值:zs)。
( s) G! [! Q5 C- H0 ^, i ' D; ?) |+ @+ G4 d# q
( m/ s$ ?) \2 b- p$ y
4)session - m9 D2 U2 {- }% z
a,什么是session?
3 }; S' \6 ~" V1 `" k. }$ v, e 浏览器访问服务器时,服务器会创建一个session
. G8 q+ n8 K* s9 J2 ? R" h- t 对象(该对象有一个唯一的id, 一般称为sessionId)
9 k# q) j5 N( u. X' O) r3 _# A 。服务器在缺省情况下,会将sessionId以cookie
- {/ W0 e8 s1 k0 ~$ q 机制发送给浏览器。当浏览器再次访问服务器时,5 a+ i( d8 E3 n/ N5 h8 T8 k- f: |
会将sessionId发送给服务器。服务器依据sessionId
5 s* K$ R$ G8 m0 {5 F 就可以找到对应的session对象。通过这种方式,
0 @; y4 A; s2 n1 V- w! a) G 就可以管理用户的状态。3 n" o, ^" t& `3 z* h7 a$ {; I
b,如何获得session对象
0 ]( L3 b0 n' X. c 方式一:
: q6 N. a J4 e. U HttpSession session =
# p9 t2 G+ S$ @6 C5 L) g request.getSession(boolean flag);1 p/ v Z( ? l
当flag = true:3 @+ X& Z: p6 `0 M' n
服务器会先查看请求中是否包含sessionId,* @0 P2 e0 U- w9 U1 P/ R
如果没有,则创建一个session对象。
7 v6 j; q9 E/ c0 \) _, C 如果有,则依据sessionId去查找对应的
9 g; c2 M W& v' n5 { session对象,如果找到,则返回。1 l3 s, O( `& u# U0 b; c
如果找不到,则创建一个新的session对象。
8 s* N( X- v$ i, H, ?" ? 当flag = false:% V2 o ^9 p/ d" b' P4 m
服务器会先查看请求中是否包含sessionId,3 f; T+ \2 k6 d1 k0 l- ~
如果没有,返回null。
1 x; M, G( p$ }* d) _$ o8 H7 K& z 如果有,则依据sessionId去查找对应的
% Z: e. R! e+ \* q/ a session对象,如果找到,则返回。' t( B! e9 p9 T% _
如果找不到,返回null。
- C4 _& o' s) D! I5 O 方式二:
' t) g! t/ N! s HttpSession session =
' l4 F+ J" G, |- R9 X request.getSession();8 i5 O; R" w' L# i) V- j* \$ e3 Q, c
与request.getSession(true)等价。9 @- p; T1 ]) F6 w* v1 W
c,HttpSession接口提供的一些方法
3 e( v( O6 @! b1 A" o- T. q$ h //获得sessionId。
) v: q) ~' E' j! x% b3 V/ h% _7 t/ ` String session.getId();4 L8 ^1 i4 V" _# E( n
//绑订数据
6 x+ ^) K+ }; c! C0 z2 K session.setAttribute(+ C4 {. ~! q( D- j
String name,Object obj);
/ s$ T$ B; U# R) `8 ^; e! P) A //obj最好实现Serializable接口(服务器4 w$ i# Q8 q1 B
在对session进行持久化操作时,比如钝化 Q9 a4 T0 V2 ?8 S8 ~* v
、激活,会使用序列化协议)。
* y' e/ P/ z7 P2 j) I C Object session.getAttribute(String name);
8 B/ b8 g. C9 I //如果name对应的值不存在,返回null。" M2 k1 Z% h9 s- p0 N! G5 J3 h
session.removeAttribute(String name);
1 s2 p) L" T, D( T d,session超时
' B' D* U( A1 B. L6 T 服务器会将超过指定时间的session对象
3 P3 d3 V. B1 u/ `- } 删除(在指定的时间内,该session对象没有
: ^2 M1 L$ M; R% _3 [ G4 u9 O 使用)。# [( s+ Q: u1 k4 I) Y
方式一:
* t: k! h) j; G4 L. E; f0 g session.setMaxInactiveInterval(
) h) I) R& D9 g* E int seconds);- d! [# z$ T5 H' V/ |, t
方式二:# N" S/ K6 H* B4 p
服务器有一个缺省的超时限制,可以2 P+ {1 X0 g1 _/ {: d3 p* N% _4 b
通过相应的配置文件来重新设置。
* O; B1 K/ I7 K+ ^8 ?& e 比如可以修改tomcat的web.xml(
3 l8 o( C; z- O tomcat_home/conf下面)。
8 B4 N9 ?1 F$ _, n) P3 J$ A <session-config>
+ j. \/ H" V/ i& N, G <session-timeout>30</session-timeout>
2 b9 _' I9 G7 _& X q </session-config>
" u( b5 O( u+ W# Z2 W# \4 ] 另外,也可以只修改某个应用的web.xml。- R, K( [9 J$ k. f0 |5 i
e,删除session
1 O# D8 K$ s# z& [; v session.invalidate();& ^' ]( ?& L: `: G# `/ p
" C$ ^. U# u9 x: F& T% |4 H
案例:0 o! W$ @6 t( Z3 A E! g" z. \# f0 \9 p
session验证
' Q) v0 u7 b( _5 c t5 ^- G) a' Q8 I U step1 在登录成功之后,在session上绑订一些数据。
# }4 M6 C+ ]0 p/ n1 X3 d( z0 ? 比如:' X" p5 J/ ?' {, \6 v v
session.setAttribute("user",user);
/ H- k% Q1 c* m' F l! d7 T step2 在访问需要保护的页面或者资源时,执行
) c( U! N/ _; J/ \8 B Object obj = session.getAttribute("user");
/ d4 T) a8 J/ E+ o 如果obj为null,说明没有登录,一般重定向到! c2 h* `# e' U. k5 z- E
登录页面。
; j6 B- u# y( s% D3 w4 H |
-
总评分: 帮币 + 5
查看全部评分
|