|
该用户从未签到
|
2、状态管理
% x7 P) n& P i7 d3 b8 k% \0 p 1)什么是状态管理
' O; n1 h+ n$ M; F$ p; q' Q( B' ] 将客户端(一般是浏览器)与服务器之间的多次4 N5 J+ q% W' d0 C: k
交互当作一个整体来看待,即将多次操作所涉及的
x& @8 \7 u3 q% e' I 数据记录下来。
0 Y: A% R" m+ \4 | 2)怎样进行状态管理
1 g$ F: n( }3 s/ { 第一种方式,在客户端管理用户的状态
- q( a* y' y5 C0 c+ n2 M; N# n (cookie)。% @) a/ e% P; z0 D4 Y0 q
第二种方式,在服务器端管理用户的状态" c( h q7 ]5 S2 q- E- {5 X
(session)。
) l( t0 L* h5 o& [/ o: M% [' { 3)cookie2 C; u3 I* U0 y0 ]; p
a,什么是cookie?, g2 ^: l/ F9 h0 P0 F
浏览器在访问服务器时,服务器将一些数据! J" m% n5 [# M5 C( ]
以set-cookie消息头的形式发送给浏览器。浏览
& @; m0 |. i7 z3 Q- P( t, } 器会将这些数据保存起来。当浏览器再次访问6 L0 q6 X, d( u) A
服务器时,会将这些数据以cookie消息头的形式( b W& s6 ~% B/ j/ T- y5 m
发送给服务器。通过这种方式,可以管理用户的/ T% k- j& z; A4 s
状态。
1 g) ?% h$ s8 @ b,怎样创建cookie?
3 q/ K- q& i; E4 w8 m Cookie cookie = new Cookie(String name,
' o9 O" D# }7 v1 c, s2 o, W3 I1 t$ G String value);
" }% y- n u" W# o4 B1 g5 p! E, z; R, H7 p response.addCookie(cookie);; M- k- |, a L3 _$ n5 W( z
c,查询cookie& a" k2 f4 R# X* ?
//如果没有cookie,则返回null。
/ d' n; T1 E" O7 a- ? Cookie[] cookies = request.getCookies();" p- x9 l/ `, G/ ^6 }" ^* p( q& d) @
String name = cookie.getName();/ ]$ A4 T' i1 M. ]- \' J& \% z
String value = cookie.getValue();& {7 {# ?* @' C' a3 ?
d,cookie保存时的编码问题' M0 m% g( b9 v5 l1 p6 [' F" w& \
cookie的值只能是ascii字符,如果是中文,# x& I* |2 ?/ ?' F. h
需要将中文转换成ascii字符形式。. ?* b1 V3 z) ^" x2 R6 ~2 @
可以使用URLEncoder.encode()方法和4 b& M% w: x- Y* \7 b& K+ ~. j
URLDecoder.decode()方法来进行这种转换。4 [; d) i! N( a/ R
e,cookie的保存时间
# n$ r( b2 U k7 T cookie.setMaxAge(int seconds);7 ~; o+ c# Z0 ?( V
seconds > 0:浏览器会将cookie以文件的方式
6 b3 R: C7 S4 n" F# u 保存在硬盘上。在超过指定的时间以后,会删除
3 J& c; m6 q* \7 s0 O& q1 u3 c1 b 该文件。7 h% U1 }+ ^1 ~8 B- p& ^* v1 E
seconds < 0:默认值,浏览器会将cookie保存
3 _3 p: e, A+ V$ v9 z3 C+ G 在内存里面。只有当浏览器关闭之后,才会删除。
. I+ m; Y+ N, q1 L/ s# j; _ seconds = 0:删除。- f, ^4 O$ g1 R1 j$ O6 `
f,删除cookie! H' X- U3 [. P" l) m# A+ ?4 y
比如要删除一个name为"username"的cookie。+ d8 M* C* ]' F: Z4 h
Cookie c = new Cookie("username","");
z; _$ y8 w: i, i N; E c.setMaxAge(0);
+ ? z% ^/ }8 B2 }. a d) a& k response.addCookie(c);
0 b# V# a& q0 U1 _. D4 \* W7 U g,cookie的路径问题' E2 G$ M! I0 P \9 k* G8 p
浏览器在向服务器上的某个地址发送请求时," R( G8 Y7 g8 E `; ~
会先比较cookie的路径与向访问的路径(地址)是
* j8 |; U" d @. d 否匹配。只有匹配的cookie,才会发送。5 x* R x5 E4 s$ y* Y" X
cookie的路径可以通过
' \1 b- q b. M5 P/ Y. F cookie.setPath(String path)方法来设置。
. E4 }+ M0 L* F; g. H 如果没有设置,则有一个缺省的路径,缺省的
2 W( _8 A, X+ T& w 路径是生成该cookie的组件的路径。
5 K: P8 w! X' ?$ s& ]) ?- L 比如: /appname/addCookie保存了一个cookie," Q* s7 \) T* U. f7 L
则该cookie的路径就是/appname/addCookie。8 h6 Z- l0 G# g4 M+ \
. ^4 n \8 }" x7 N; p
规则:
6 u0 C! R( r0 r* G cookie的路径必须是要访问的路径的上层目录
+ Q. ` h7 D b, k3 M; Z0 E: A 或者是与要访问的路径相等,浏览器才会5 w6 g4 `$ H' y
将cookie发送给服务器。
+ X& f# u! B+ {- Y: p) a f% N1 |3 [. b- E/ D
一般可以设置setPath("/appname"),表示访问
- v: B w9 X/ y' `2 B 该应用下的所有地址,均会发送cookie。0 p9 B# Y, ?- p3 \# ?+ M
h,cookie的限制
0 p" D0 c3 F/ U7 x* s2 ~ cookie可以禁止
* D' ], M- k* j$ L; j# x cookie的大小有限制(4k左右)& A1 z# ^1 q# y
cookie的数量也有限制(浏览器大约能保存300个)
2 s) t/ J: r2 u2 S9 f( b cookie的值只能是字符串,要考虑编码问题。9 Z/ [0 k n) q
cookie不安全1 Q, [/ w( @2 D. h, b' \3 A5 o
练习:
- d# M7 Z2 V; p 写一个Add_FindCookieServlet,该servlet先查询4 q; j) k- W3 x: \1 N& H
有没有一个名叫name的cookie,如果有,则显示
) r; g( g# w/ w0 O! b 该cookie的值,如果没有,则创建该cookie(
3 Q8 q3 e, P: R6 ~9 t4 m9 ` cookie的名字:name,cookie的值:zs)。
2 N( k1 {" e- K3 }+ L0 t9 f 3 x( A2 _# Z/ W# |
4 l- Q4 }. K* O8 c% B, p' S
4)session , Z% {5 M" w+ Y: E. a# T
a,什么是session?
4 W6 [" ^/ e# q3 O$ h% }6 u5 P4 I: N. Z 浏览器访问服务器时,服务器会创建一个session2 S' H; J1 @* c& t9 T6 E
对象(该对象有一个唯一的id, 一般称为sessionId)
- t# i) e1 l8 m a 。服务器在缺省情况下,会将sessionId以cookie
$ r1 s: \: o# |7 h/ i( x 机制发送给浏览器。当浏览器再次访问服务器时,
2 R8 g2 C }" I& @# k: ? 会将sessionId发送给服务器。服务器依据sessionId
; g2 r- f) j; Z1 ?8 W$ N 就可以找到对应的session对象。通过这种方式,# c1 a+ G0 C4 M& F7 c" t8 v; [6 n0 o
就可以管理用户的状态。! X8 z M/ i( d0 E8 A2 }3 R
b,如何获得session对象6 |2 c! l/ ?# s# v: ~ ?- K
方式一:
* g2 T* s% V9 E HttpSession session =
5 |1 I3 [1 [0 A8 }, i; K request.getSession(boolean flag);5 H2 {0 T- |- n# A
当flag = true:& a' p5 F5 `5 ^' M
服务器会先查看请求中是否包含sessionId,
8 f( A% p7 p8 Y5 L8 l: B6 D* ? 如果没有,则创建一个session对象。5 @* d# s o" L, j+ Y3 O
如果有,则依据sessionId去查找对应的0 c% f9 E* e+ r
session对象,如果找到,则返回。6 C& ?- {2 j% V0 R" m
如果找不到,则创建一个新的session对象。. ^3 P( a! S) c
当flag = false:
0 z1 l/ j: N: v! `4 J a. g Z 服务器会先查看请求中是否包含sessionId,1 F" A; K: @3 Y2 J$ E+ ^% D. d
如果没有,返回null。9 o: ~4 ], C ` t$ k4 Y5 {9 s( h
如果有,则依据sessionId去查找对应的
. E7 \- r R n, n U; Q x session对象,如果找到,则返回。
9 s) t6 d+ U$ A# V3 K 如果找不到,返回null。3 o( f0 D2 ?4 k! N9 C3 @
方式二:
0 N- P2 |+ k3 p0 A8 d, _ HttpSession session = ' p+ w5 f/ ?$ c3 S1 _" |. c" T
request.getSession();
# n! a/ d6 K3 E& ]' m 与request.getSession(true)等价。
" l+ x- y8 |% w% X, X# G c,HttpSession接口提供的一些方法- S1 L# ?: h+ I5 v' m8 w" G
//获得sessionId。
7 Y) I% \2 k6 ~2 i String session.getId();* r7 h* s ?' X$ P, R
//绑订数据
& E; k$ |' S5 V& L) B% f session.setAttribute(
9 a2 p7 [7 x. [, I& N$ f. ^# d String name,Object obj);
' N* q' }# K+ K$ F, O //obj最好实现Serializable接口(服务器
# v0 u8 q. x% ^5 Z# t) X 在对session进行持久化操作时,比如钝化8 _ h0 B. [' k t! w+ D" @1 M4 d, b
、激活,会使用序列化协议)。& p! {6 C& ]( B; k# C# L% _" s! E8 I- Y
Object session.getAttribute(String name);8 J3 I- f: Z6 f+ J' x8 Y
//如果name对应的值不存在,返回null。$ R7 u9 ~8 Z2 m0 H8 K
session.removeAttribute(String name);
/ M i# v2 t. _3 p3 s d,session超时
( r$ z1 O# O$ q+ S' y 服务器会将超过指定时间的session对象6 V: ~% ]. B3 ^5 ~0 d9 [' {. a. @- z
删除(在指定的时间内,该session对象没有: H! U) h. |5 q% @, V, V1 q8 q$ w
使用)。
! ^. Z+ s2 |4 n* a5 g9 L i0 ~) T0 C 方式一:
* {1 L% \" m, w; u+ I) y$ B session.setMaxInactiveInterval(
* ?, Q' y& @' r8 m' m8 k int seconds);
) y- P" J" `/ k: w. p; m: t 方式二:' ]' V# G, ?0 M2 F9 d( ^ Y+ S2 m
服务器有一个缺省的超时限制,可以7 g5 T: i) G7 k: e: {. C) a: e
通过相应的配置文件来重新设置。
/ ~% F1 P6 ^; p! Y5 [3 | 比如可以修改tomcat的web.xml(
( b; n' e6 d4 v J9 y, a* Y- n tomcat_home/conf下面)。
* i% g# ]% j9 a5 l, t5 j <session-config>% |4 j% ]5 i$ }% w* I# M: b9 k
<session-timeout>30</session-timeout>5 r- m8 E/ `4 o) H- h- E
</session-config>
b% F! `; O7 k) ?: W5 I6 a+ S 另外,也可以只修改某个应用的web.xml。
0 k8 a2 z# d7 K: P2 d, h& |/ U! J e,删除session0 G* W3 p: i* G
session.invalidate();
( t6 Y& Z; D3 p- m# a5 U5 P# \
4 s" [) J1 M7 J; l 案例:
$ U' Y( r+ z4 @: j" {% h session验证% e3 d' i; B! v7 d3 E
step1 在登录成功之后,在session上绑订一些数据。
" h6 G% m+ Y) d) M' [+ O, }0 w$ n 比如:$ c* n" y5 c [7 L$ E0 q
session.setAttribute("user",user);4 ~# K* l- n8 R, n! v8 h: O1 g
step2 在访问需要保护的页面或者资源时,执行- h$ I$ V' h: _7 m
Object obj = session.getAttribute("user");' q" Y+ \. h0 _" B3 {! g
如果obj为null,说明没有登录,一般重定向到
9 f- d5 j* C" @$ x% \5 F: V9 g0 Y 登录页面。
0 n `$ a7 o; ~9 C, ]1 v5 h |
-
总评分: 帮币 + 5
查看全部评分
|