该用户从未签到
|
2、状态管理
: v( T0 f0 v' u) p* q" n- ~ 1)什么是状态管理
$ A* m `6 C& A1 a 将客户端(一般是浏览器)与服务器之间的多次
2 B, h2 {8 [0 a% T5 s* q 交互当作一个整体来看待,即将多次操作所涉及的- C! Y% @. o1 G1 i3 }" q
数据记录下来。
5 O% {$ G; O% I9 A" G* W8 l3 N 2)怎样进行状态管理* l% @ h9 P; q* m! j/ E
第一种方式,在客户端管理用户的状态
3 Z8 y4 t2 E! K2 H (cookie)。
# U l* t$ N$ I& a 第二种方式,在服务器端管理用户的状态
0 @" r* K5 S/ P4 }, ]8 w" } (session)。5 }& Q9 S/ @+ M, K
3)cookie4 V4 U8 { a' k. O
a,什么是cookie?0 `& s! f; I* L$ H4 V
浏览器在访问服务器时,服务器将一些数据8 F! p( M0 C; o, V% g& y. a
以set-cookie消息头的形式发送给浏览器。浏览. X1 ?1 i0 p9 v* J) a4 J* g
器会将这些数据保存起来。当浏览器再次访问
" W. n; l" N, a' y0 w 服务器时,会将这些数据以cookie消息头的形式
3 ~# {. w) l- Q, y' B+ i0 d) W 发送给服务器。通过这种方式,可以管理用户的; y7 e8 V' o2 Q/ {" D
状态。$ D# y3 ^1 v2 C% E
b,怎样创建cookie?
9 V( ~( d8 J2 b# f# M t- q0 F Cookie cookie = new Cookie(String name,
1 i& N( l" I; K0 ~4 j String value);
" l, _9 D4 c' i; u% e5 z7 m9 I response.addCookie(cookie);) g$ E2 R5 w9 x' v ^7 @
c,查询cookie
! z, R# `$ |( G- X! W. S7 ~ //如果没有cookie,则返回null。$ t: V* v' u9 @4 P) d# J
Cookie[] cookies = request.getCookies();7 ~( c7 |/ |, K( e3 y X* E; k
String name = cookie.getName();
* O3 t* ]& [+ T" D8 a String value = cookie.getValue();: h( O! g% T: b a0 j1 r
d,cookie保存时的编码问题4 k+ D3 ~3 e; s0 t5 N/ f4 g, T
cookie的值只能是ascii字符,如果是中文,% A: l: @. `1 Z q; O
需要将中文转换成ascii字符形式。" L, }9 ~! V I7 a# J
可以使用URLEncoder.encode()方法和# v$ q; [& _& m
URLDecoder.decode()方法来进行这种转换。( s2 q4 V; H( K% s, t$ t R
e,cookie的保存时间
& S' V q$ g( [4 F cookie.setMaxAge(int seconds);
# k s/ z7 `! x2 B& I0 G! w seconds > 0:浏览器会将cookie以文件的方式
& t3 m6 G) P! y9 O+ G1 t 保存在硬盘上。在超过指定的时间以后,会删除6 v- }( u# y" x7 `8 j, ]* B
该文件。$ [: d9 l7 d. |# V5 Q
seconds < 0:默认值,浏览器会将cookie保存$ {! y* M0 E) D: p/ f1 a
在内存里面。只有当浏览器关闭之后,才会删除。5 f+ x' D) y+ G6 a
seconds = 0:删除。8 ^7 _( Q/ z5 u$ a, q: S
f,删除cookie2 \3 c6 X( J1 |, Q' k# h N
比如要删除一个name为"username"的cookie。
( f6 z+ L' u+ P1 ?$ S Cookie c = new Cookie("username","");
: R4 F' Z) C1 m% V8 r c.setMaxAge(0);
& f1 U3 a M7 P1 S, p' {4 W" R. e response.addCookie(c);0 h# ]7 _( [: g; {& t
g,cookie的路径问题
+ l5 _, D4 i" k. ?: B1 i* { 浏览器在向服务器上的某个地址发送请求时,
6 ~% ~6 t% d7 `# l7 r3 N! c 会先比较cookie的路径与向访问的路径(地址)是
4 j1 H2 I3 Q8 q5 P 否匹配。只有匹配的cookie,才会发送。
9 w+ w: J: H7 M. X8 H- W' A: ? cookie的路径可以通过( D, D7 k4 B* ?1 d/ R6 l' u
cookie.setPath(String path)方法来设置。* D& b* I5 h ?
如果没有设置,则有一个缺省的路径,缺省的
- ]9 h A3 \ `2 B; s 路径是生成该cookie的组件的路径。5 g% o5 e/ t9 d5 l! j% s
比如: /appname/addCookie保存了一个cookie,! d) i7 n+ c! p$ {& \0 J
则该cookie的路径就是/appname/addCookie。
- n }# m6 E" @ n: x 5 y8 A4 g; U) w/ V; Z% b* a e2 \* ~9 t3 k
规则:5 N3 S8 I M" S- S
cookie的路径必须是要访问的路径的上层目录/ t/ B W2 c% ?
或者是与要访问的路径相等,浏览器才会1 w% K% m ]$ _1 y
将cookie发送给服务器。( } B: k+ ]- g4 o
_3 i. o' c# N: s; o 一般可以设置setPath("/appname"),表示访问
' c& Y0 s1 [2 O! r6 j- S5 T4 x. H. ?. v 该应用下的所有地址,均会发送cookie。
4 ]8 g: _% i1 P" [, U h,cookie的限制0 H3 S+ P k1 L7 n5 x w k1 _
cookie可以禁止
. a" c8 t/ m! A% Z2 r7 x9 e cookie的大小有限制(4k左右)
( ` e. t$ F% e0 _" D3 e cookie的数量也有限制(浏览器大约能保存300个) 1 D! W, m2 }6 y8 n4 r! h2 c
cookie的值只能是字符串,要考虑编码问题。2 C5 M* I+ O$ u1 T" c% O
cookie不安全
+ f* F/ q6 O" T+ L, ] 练习:0 b/ C8 _# z+ ^- H
写一个Add_FindCookieServlet,该servlet先查询
" D( D0 g% `2 J% x% Z 有没有一个名叫name的cookie,如果有,则显示4 x/ ~5 Y. \" _: |; q; b0 `6 W
该cookie的值,如果没有,则创建该cookie(; J4 B+ N: ~' W; D
cookie的名字:name,cookie的值:zs)。
z2 g6 x' C0 m K( J 5 ~) t5 x. t- _" A1 J1 p
6 U; W/ ?: s0 o. Q+ O6 M
4)session
) t8 f5 r: W8 e3 d1 Q8 p a,什么是session?- B0 c# T" E/ {9 c
浏览器访问服务器时,服务器会创建一个session
8 }& P+ V% s/ R- o 对象(该对象有一个唯一的id, 一般称为sessionId)7 ^; x. M. Y. h+ M5 J! f+ G
。服务器在缺省情况下,会将sessionId以cookie$ m5 L+ P9 N6 q
机制发送给浏览器。当浏览器再次访问服务器时,; u: d& _6 \9 q$ ~/ B; C
会将sessionId发送给服务器。服务器依据sessionId0 N6 q* }% ~. Y+ U9 n
就可以找到对应的session对象。通过这种方式,. c% v; L B# Y% Q. I6 z
就可以管理用户的状态。) _7 Y6 w E+ h+ j; q+ \- C
b,如何获得session对象
' {) m" Z; A! \4 P8 ^$ e 方式一:* U! n9 _. ]+ _6 i! U. ~. ^" n# _6 A
HttpSession session = . u4 R) X/ d6 H. D# h
request.getSession(boolean flag);" o( p" X( C0 D6 @7 t7 t' }
当flag = true:
$ q5 X" a3 A3 N: c9 Z7 ~0 Y7 t( W/ T 服务器会先查看请求中是否包含sessionId,
# c& t" @) b0 C7 }0 X! h! n; s$ [ 如果没有,则创建一个session对象。
8 g# o" _9 `" R N 如果有,则依据sessionId去查找对应的 u5 g( g6 C$ D; T1 K4 x f/ A2 H. f
session对象,如果找到,则返回。
4 T3 M/ q$ \6 ~' q 如果找不到,则创建一个新的session对象。0 E: h E3 z0 M; h& {# ?- @+ y
当flag = false:
- T$ o# K8 R$ P0 l& ?" z 服务器会先查看请求中是否包含sessionId,4 t! v: z2 o' b7 B
如果没有,返回null。
. ?7 q0 P! o1 f4 d 如果有,则依据sessionId去查找对应的
7 y6 L: ^, w5 n. X) Q; S( f session对象,如果找到,则返回。
- @. s9 G3 n) B* V) g7 M/ S: _) R 如果找不到,返回null。# C7 i! c& k$ i$ J, V! ~7 \
方式二:
( {0 R \* h6 s. ^/ \1 S8 u HttpSession session =
( P& i% E4 J' q- [# A; _ request.getSession();* d% k; @, \+ _# d1 I
与request.getSession(true)等价。) T9 O5 E U2 t+ p5 ]2 v/ X
c,HttpSession接口提供的一些方法
+ U; u0 I+ k$ [2 O% ^0 e //获得sessionId。' L- G* a2 G: `. U$ i3 L( N
String session.getId();+ ~' e: o7 C) n; W
//绑订数据
8 ^: t9 P9 i' @8 C+ o( n3 B9 M session.setAttribute(- {8 ~* j; P- Q& {5 Y3 F. l% Z
String name,Object obj);
& r1 |4 x) q2 Y3 U //obj最好实现Serializable接口(服务器7 Y! `9 i0 Q* W6 x
在对session进行持久化操作时,比如钝化
7 J# m+ Q0 C; C* W" p 、激活,会使用序列化协议)。! ~4 G9 N$ H: C& h' u& ?
Object session.getAttribute(String name);
( Q* h7 V$ H* c //如果name对应的值不存在,返回null。! |) Y- U! i; K# z; h; L& U; @
session.removeAttribute(String name);, ]) v6 v) V: o
d,session超时/ _& q* I- y* d* x+ V4 b; E5 R
服务器会将超过指定时间的session对象+ C7 R/ N: x" w) w4 M2 t( w) U
删除(在指定的时间内,该session对象没有
6 s# P# Z6 d! u( d 使用)。) [5 d; e; ` W% _
方式一:( ]( H/ J. }9 g, \4 \6 _! z
session.setMaxInactiveInterval(7 Q! d' ?( Z. r D5 D T
int seconds);7 ^0 A1 i1 ^9 m+ o# o
方式二:2 E/ l, L8 G: ?7 [5 e
服务器有一个缺省的超时限制,可以
: W* r: E% N9 G5 ~5 V0 b+ I 通过相应的配置文件来重新设置。
2 B% L" t d" [4 { 比如可以修改tomcat的web.xml(
) K; c# Q' f/ I9 b7 o) c tomcat_home/conf下面)。
# t. b3 }, t. t <session-config>
; k9 \: _+ o$ K% u6 Y$ y) ^ <session-timeout>30</session-timeout>
C* ]) d$ ?7 @ </session-config>
. u N3 {8 l6 h' K 另外,也可以只修改某个应用的web.xml。
, D V0 `6 a4 i& J X6 k# |1 | e,删除session0 N# W5 G9 f" G5 R
session.invalidate();
5 N+ K" n: d4 \' ~, `8 r 9 u7 x( s0 X& h( u3 ~ `$ g3 \
案例:
, H- {+ z/ u2 m2 r session验证
0 R. [) M: y6 N) P7 m step1 在登录成功之后,在session上绑订一些数据。
2 x7 P) \- Z4 F. l 比如:
" d8 l/ Y3 ~1 Y1 t' q session.setAttribute("user",user);
6 N) M! x, i6 ^( [# N4 s( S" U step2 在访问需要保护的页面或者资源时,执行0 Z/ j9 }2 Y; e: n! i: j
Object obj = session.getAttribute("user");4 s7 }3 {0 z5 V5 S
如果obj为null,说明没有登录,一般重定向到
/ S% k% [4 `2 v% a* y. g. b 登录页面。
( i* ?$ h/ e! C) U |
-
总评分: 帮币 + 5
查看全部评分
|