该用户从未签到
|
2、状态管理
5 p5 A- F: r# o. y& ~ 1)什么是状态管理
3 B9 l' m2 w& Q# m+ c, P3 x 将客户端(一般是浏览器)与服务器之间的多次
3 w* x; i9 \) V 交互当作一个整体来看待,即将多次操作所涉及的6 b6 u0 Q) g; B) {$ k+ }/ `3 h
数据记录下来。( r0 R0 d2 H1 }- t/ T% N" L
2)怎样进行状态管理
b$ b0 D4 i: u4 I 第一种方式,在客户端管理用户的状态
1 C; q- p* S/ U$ z (cookie)。
X0 y5 p+ o( h# B& u4 |$ e 第二种方式,在服务器端管理用户的状态8 T8 B6 s: ^9 {
(session)。
/ w1 I* { W" z3 F4 Y3 \ 3)cookie
: g, Z7 B% k5 y7 H. m a,什么是cookie?, G- ]& I' v" r% r1 K, t6 g
浏览器在访问服务器时,服务器将一些数据
% _9 Q4 `. ?+ y5 P% u- L" E4 V) _ 以set-cookie消息头的形式发送给浏览器。浏览
5 u8 c+ y3 ~2 k6 i 器会将这些数据保存起来。当浏览器再次访问
" T) F' X$ f0 F% Z( w 服务器时,会将这些数据以cookie消息头的形式, M" F- ~3 V4 k% }+ ?2 c
发送给服务器。通过这种方式,可以管理用户的
+ q$ X1 m+ N( }# z3 [( o: I 状态。
/ F7 s' x1 f. Z: u* R b,怎样创建cookie?- G4 j; u% e; f8 t5 o
Cookie cookie = new Cookie(String name,
! d: s, o7 P+ G String value);) ]# Y& Y5 [0 H [
response.addCookie(cookie);
+ H8 v6 _; W+ S. b" O$ q c,查询cookie
# S# v0 P) Q# G0 h* T' ~2 j4 u //如果没有cookie,则返回null。+ \6 @+ z; z; O5 x. g, c8 z F0 k/ _
Cookie[] cookies = request.getCookies(); B; h& d7 y. K' H; D3 L; Y
String name = cookie.getName();/ O. u4 V0 B, N7 c% M; L
String value = cookie.getValue();
2 I- z( S8 ~0 L7 _3 X d,cookie保存时的编码问题
: A4 A- z$ C2 y: _0 ~ cookie的值只能是ascii字符,如果是中文,- ^) \+ b/ `/ q/ B7 D+ N
需要将中文转换成ascii字符形式。
, w& G3 ?9 P. f6 _ 可以使用URLEncoder.encode()方法和0 R v( n4 g7 y& r' x
URLDecoder.decode()方法来进行这种转换。
8 G4 `! m2 u" s$ c: j/ G$ _ e,cookie的保存时间
2 c7 g3 B; X5 ?( _ _6 P$ J cookie.setMaxAge(int seconds);
8 h* `( n" N) p. t, o9 a9 J* m- P seconds > 0:浏览器会将cookie以文件的方式5 H/ p0 C1 l: e6 O: \: d1 @' i
保存在硬盘上。在超过指定的时间以后,会删除6 J, c- Z8 d. \6 E: S# j' f1 g
该文件。
+ X$ u5 o; ?7 E+ b7 Y seconds < 0:默认值,浏览器会将cookie保存
4 v/ `, ^: R/ U$ j. j9 { 在内存里面。只有当浏览器关闭之后,才会删除。
4 P, o( H. o6 x seconds = 0:删除。
/ B% t3 _* {$ `3 y* m8 ~' ? f,删除cookie* p) ]1 R( i9 I3 W' D% ^/ U; d }# Y
比如要删除一个name为"username"的cookie。1 K1 N3 s5 s8 Q2 y+ Y8 \. ~
Cookie c = new Cookie("username","");3 K; x0 n; ]' e$ u2 _ U* U
c.setMaxAge(0);% G! g% X1 p' }
response.addCookie(c);( U6 T4 a6 T8 F6 x; D% u0 d" f$ Q
g,cookie的路径问题$ t! N. ]! Y6 {& q& u
浏览器在向服务器上的某个地址发送请求时,
$ W) f+ v3 F# K7 \0 @( w3 k$ { 会先比较cookie的路径与向访问的路径(地址)是
, J$ N2 M) f# K; `9 b" ^ 否匹配。只有匹配的cookie,才会发送。
! R. ?% I5 f% ~5 o cookie的路径可以通过( `- B ?! _9 T5 D& c/ [* W
cookie.setPath(String path)方法来设置。
4 J; A5 y9 ]: g5 _! F 如果没有设置,则有一个缺省的路径,缺省的. p/ a( D. n# S
路径是生成该cookie的组件的路径。1 s' E3 ?) P4 J- d( ]4 k9 i. Y
比如: /appname/addCookie保存了一个cookie,' Y$ O* M" _; {$ d3 t1 m
则该cookie的路径就是/appname/addCookie。
X& b+ b( k1 H- e, V) ~( d3 H 9 }+ l' x" E3 D( Y: J5 q- }( a
规则:
i% p+ |7 @# z3 d0 l cookie的路径必须是要访问的路径的上层目录
' J9 b0 |4 T1 Y) H" @$ N4 X 或者是与要访问的路径相等,浏览器才会- \ V* \7 t, U+ A4 h- ]% {) y0 f8 G
将cookie发送给服务器。4 Y \! Q/ q( B: y0 k% T. \ S
9 S2 d9 B" ?) a6 k1 f) N 一般可以设置setPath("/appname"),表示访问2 }2 P* s; b* I5 |9 f3 g4 Z% x
该应用下的所有地址,均会发送cookie。
) q. b; ?4 s% s1 N* o h,cookie的限制
% y9 L- K( Y/ O6 R cookie可以禁止
( O2 K; o" r$ d) I- s# `/ ^ cookie的大小有限制(4k左右)2 f% [2 D0 A, F6 e3 J
cookie的数量也有限制(浏览器大约能保存300个)
" A0 Y1 G: T5 ], @0 E5 v4 o6 j; f cookie的值只能是字符串,要考虑编码问题。
0 o. W2 q9 E9 Y+ ?1 ^9 E6 Q. b cookie不安全
5 D# [; ?6 M& n0 _, z; ` 练习:# q4 C% s/ p/ b
写一个Add_FindCookieServlet,该servlet先查询$ ^: Z7 ~7 ]3 p# n' S
有没有一个名叫name的cookie,如果有,则显示
3 v( U7 k- h; q1 X: b4 T 该cookie的值,如果没有,则创建该cookie(
. I$ A% z O8 @4 s cookie的名字:name,cookie的值:zs)。3 Q" V' C8 h8 R1 L# O1 f
, N9 H1 Q, U( S# `" j
p: R) u7 p4 t7 s" z
4)session ! Y. m+ m+ V1 ]1 c+ B7 T
a,什么是session?$ @7 O! {7 H4 a. B/ _, |
浏览器访问服务器时,服务器会创建一个session
$ g1 R' i1 ~3 k' d, W 对象(该对象有一个唯一的id, 一般称为sessionId)
& G8 z+ T( V1 k# [5 e0 r. k" j1 y 。服务器在缺省情况下,会将sessionId以cookie/ Q$ y1 _6 E& C0 m8 F
机制发送给浏览器。当浏览器再次访问服务器时,7 `0 E* m$ D7 v) G
会将sessionId发送给服务器。服务器依据sessionId
; v0 R$ ]1 N ^. L$ y: b 就可以找到对应的session对象。通过这种方式,
8 H2 T0 H j3 ?7 ~5 m 就可以管理用户的状态。
2 m0 T, a" ^7 J* w# d* V b,如何获得session对象2 y: C& l: ^3 g. ?# e
方式一:" F9 e: y$ h: u7 Y
HttpSession session =
! ^/ C9 m* j' R* r9 J request.getSession(boolean flag);
& H! g- F- m" F 当flag = true:' X6 S w1 E: e
服务器会先查看请求中是否包含sessionId,9 V3 h& Z! A8 S
如果没有,则创建一个session对象。+ o; V6 p. U' `! v0 p3 z8 }( {
如果有,则依据sessionId去查找对应的
% v# q( m) a3 O4 h% ]( q session对象,如果找到,则返回。% B: \8 p& l, e9 Y; c5 a
如果找不到,则创建一个新的session对象。8 J% _% O% v# n+ g; D0 H5 u
当flag = false:
# l; n9 m6 p1 G F+ L; e3 \6 A5 ~/ g2 T 服务器会先查看请求中是否包含sessionId,( _' Y# U# r- Y! L/ ]7 {
如果没有,返回null。
7 A3 i5 Q+ e K4 Q u8 N: W 如果有,则依据sessionId去查找对应的
- x4 }: k% e: {9 C* g session对象,如果找到,则返回。) v6 E. |! E% B
如果找不到,返回null。# r( u: a6 U% S9 e& Z% T
方式二:
! f4 n" r' b# l# \) A HttpSession session = - ]9 ~( f" g9 k$ P' u; x% ?' |, H
request.getSession();
+ v3 ^/ Y) d' \. y 与request.getSession(true)等价。
' q. b/ n! S1 x2 ^9 J c,HttpSession接口提供的一些方法" v: S( R6 h* h5 {, q3 L1 u2 d; P% f
//获得sessionId。9 L! N9 n& O! m1 J
String session.getId();
7 x: s9 C$ G5 w7 F //绑订数据
9 V/ C/ {) a, T/ n+ Z9 U# | session.setAttribute(5 |$ c4 A! r% ~
String name,Object obj);; B1 [7 V. b: ?8 V1 `- p. D
//obj最好实现Serializable接口(服务器
6 u: T& x% m$ |- t 在对session进行持久化操作时,比如钝化; B' x& y* x. F
、激活,会使用序列化协议)。
% S0 x3 l/ ~9 i( M Object session.getAttribute(String name);
% A h# o( g7 N5 A: }5 i8 L5 ] //如果name对应的值不存在,返回null。
2 C, k: e& M& X: _& W- \8 } session.removeAttribute(String name);8 {2 C [5 \6 D: A: `& g
d,session超时
1 @# ~: [. L4 t/ { 服务器会将超过指定时间的session对象5 N3 E. U, Z, j$ H$ k8 K
删除(在指定的时间内,该session对象没有4 u" h" @0 @* C5 z. J4 p, `- v, f
使用)。
' C4 t, y3 S" x3 K 方式一:
: k$ S! P' d3 F5 R0 h3 P& Z session.setMaxInactiveInterval(1 O+ M* p+ `+ O$ m" W0 c2 B
int seconds);
5 l9 g& H2 W' j: p. K 方式二:
0 t" C9 M1 `9 b3 x# M7 c6 y 服务器有一个缺省的超时限制,可以! j7 @9 B( x! `9 P& E
通过相应的配置文件来重新设置。
+ l9 B: {* X* p. E! @9 A 比如可以修改tomcat的web.xml(
9 T" n. v5 Q! L8 `9 _ tomcat_home/conf下面)。6 k% p+ U' x" `7 X; E
<session-config>8 ^8 J( c! s& b: A& m. F
<session-timeout>30</session-timeout>0 m" a9 Z0 k4 B8 `1 j$ ~
</session-config>
3 j( y6 ]. `# n1 T1 s 另外,也可以只修改某个应用的web.xml。 { l7 A# [3 f4 p; O: D- \
e,删除session7 I( s( E2 l7 }8 y
session.invalidate();8 a) D+ M2 U; U3 [% t+ o- y% V
8 W1 e4 G& Y. w I1 } 案例:
5 L G& d3 Y7 j+ { l/ W* C session验证
) K' @; Y; n6 x( R# h2 E: D step1 在登录成功之后,在session上绑订一些数据。1 q8 Q x1 t3 J( u! @
比如:
% i) I+ U. W9 u+ v session.setAttribute("user",user);) k, z- S4 @ {: ^
step2 在访问需要保护的页面或者资源时,执行
5 U! S" J1 b# r% u Object obj = session.getAttribute("user");
: }% Z$ h( z2 V/ r# R/ m4 ^ 如果obj为null,说明没有登录,一般重定向到 A/ P8 @! n$ M! e
登录页面。
: X% D* o: R U |
-
总评分: 帮币 + 5
查看全部评分
|