该用户从未签到
|
2、状态管理
% R+ ]1 q9 I2 B9 r& I' d 1)什么是状态管理8 D1 y8 i$ I: n. {; G2 g
将客户端(一般是浏览器)与服务器之间的多次
' i- Y/ |8 h; q1 O4 J' B 交互当作一个整体来看待,即将多次操作所涉及的4 T% L( n" U( m
数据记录下来。
: ?* r' `& \) l0 J% e8 T; ^ 2)怎样进行状态管理
: w+ R% L) w5 N 第一种方式,在客户端管理用户的状态+ ^% l9 k# q. f* Y- f& R: X* l
(cookie)。
# h, `# {/ c& O+ J+ u 第二种方式,在服务器端管理用户的状态/ q! i! x6 k1 \- q9 u4 ]4 S8 o
(session)。8 K' M0 i$ ~8 R0 K
3)cookie' v5 ]5 ?. Z4 [0 c! a' ?0 D# w# V$ O
a,什么是cookie?0 ~# k) c9 x7 p
浏览器在访问服务器时,服务器将一些数据
6 _1 R4 n: K2 x" J( C: S' B 以set-cookie消息头的形式发送给浏览器。浏览
$ B% F3 f! S( b; O: c" R 器会将这些数据保存起来。当浏览器再次访问
2 d: V5 j7 }; s1 L 服务器时,会将这些数据以cookie消息头的形式
5 T0 h: K! D1 Q, P! s# G 发送给服务器。通过这种方式,可以管理用户的
5 n: n% }3 u0 I9 _$ N 状态。& K4 |- c* `$ h+ ] s N4 X. Y
b,怎样创建cookie?) t0 J$ j5 R3 X3 K
Cookie cookie = new Cookie(String name,
) p1 e4 C1 [# B1 P' u: T String value);1 R4 T2 l0 F; p; S$ w7 ]2 G6 T) }" B
response.addCookie(cookie);
$ b7 j- G/ F( z+ U6 q: R& ] c,查询cookie
6 w9 [& A$ f/ m: Y //如果没有cookie,则返回null。' C Q3 `# b* d% j
Cookie[] cookies = request.getCookies();$ i: G4 r, C9 h7 v) @2 f5 q: z
String name = cookie.getName();
! F( V( b* G" L, s1 n" ~; H- B String value = cookie.getValue();6 z5 [- `* } u
d,cookie保存时的编码问题
. c% J% X. y# F cookie的值只能是ascii字符,如果是中文,& o' N4 {/ X: `; C# B0 j
需要将中文转换成ascii字符形式。 w' `# h* }3 U5 |3 K% Z' l& U! z
可以使用URLEncoder.encode()方法和
5 g5 T6 [2 B9 C/ r8 J. n6 C" | URLDecoder.decode()方法来进行这种转换。" G( O: i3 j! x' E# R
e,cookie的保存时间
; e+ u5 r& ? I3 \4 g, r! H cookie.setMaxAge(int seconds);# \! a1 \: Q ~( |/ ~8 \
seconds > 0:浏览器会将cookie以文件的方式' _$ @/ k. n/ j6 L2 B
保存在硬盘上。在超过指定的时间以后,会删除
* z, x0 ?( |* v1 a" B" a 该文件。) U# s& n! `! y* x( T
seconds < 0:默认值,浏览器会将cookie保存; J/ }7 u% u9 w0 O7 B7 R- ]3 u1 d
在内存里面。只有当浏览器关闭之后,才会删除。
) ~- l6 `7 e; I seconds = 0:删除。
5 u6 L. c- b/ F" M7 K f,删除cookie' P- m5 p; s* u+ i
比如要删除一个name为"username"的cookie。9 X9 Z; y7 @* _6 X( ]) H v
Cookie c = new Cookie("username","");
5 @% A/ d, v8 P. V2 r# M c.setMaxAge(0);& ]# e2 @- K7 |& a
response.addCookie(c);
# K4 F: E: o+ X+ a+ g g,cookie的路径问题1 `% G/ J; o9 G
浏览器在向服务器上的某个地址发送请求时,
8 C/ C2 K" |8 Z 会先比较cookie的路径与向访问的路径(地址)是
% q5 S6 J& E: ` 否匹配。只有匹配的cookie,才会发送。
9 Y/ P1 p. j3 c. ~ cookie的路径可以通过$ } a/ w! n/ c9 t, e, @
cookie.setPath(String path)方法来设置。( N. C; R& M, `& h7 Y' v
如果没有设置,则有一个缺省的路径,缺省的; G" z, X1 u% D0 N. q/ T1 W# Q
路径是生成该cookie的组件的路径。/ x4 l6 G- F3 E( |% s r
比如: /appname/addCookie保存了一个cookie,; `$ w! J Q( }# T3 T5 _. z$ U- B
则该cookie的路径就是/appname/addCookie。
- A( u2 w7 P- T9 d6 k8 B6 f , q# e4 ~4 Z' B q! y
规则:
, @! Y# |- m. g; j- n1 c/ q cookie的路径必须是要访问的路径的上层目录
, o4 B" H- o0 H$ f3 O! z/ c$ F$ v. a 或者是与要访问的路径相等,浏览器才会
* [$ L% j3 w- r. u6 Y8 _ 将cookie发送给服务器。
P5 l: B+ D+ V: m2 S- l & c- R$ h ~7 P
一般可以设置setPath("/appname"),表示访问& p3 F5 h" L9 G: `3 @
该应用下的所有地址,均会发送cookie。
6 w0 H% }$ j9 c: w1 p0 T8 x h,cookie的限制) l$ }. x2 k" Z; m4 K8 [5 W$ z
cookie可以禁止& G3 i7 I, _( y5 G
cookie的大小有限制(4k左右)
' R% V& d. j* D( d! w cookie的数量也有限制(浏览器大约能保存300个)
9 r" R- V3 v, G! a" _ cookie的值只能是字符串,要考虑编码问题。
: U2 ]: [" T7 \8 z/ f cookie不安全9 S: D* m' P R4 F' Y. k. u
练习:* `- c) H5 M4 e9 _
写一个Add_FindCookieServlet,该servlet先查询3 E( q" l( L. R: n/ A" ?
有没有一个名叫name的cookie,如果有,则显示# o' I/ o5 U! s% f1 x* J' R7 R
该cookie的值,如果没有,则创建该cookie() F: L: r' n) m% b% ~7 h" U
cookie的名字:name,cookie的值:zs)。$ l" Y2 e; u y1 Q+ l" p! D
7 \6 a, d1 S0 N0 C. |
: _3 z+ F# n7 Z/ c 4)session
* l. P$ h2 w$ g) u( S/ W a,什么是session?' J1 ~9 O/ L8 K3 E6 N3 X- j
浏览器访问服务器时,服务器会创建一个session
5 G0 a5 e, Y. Z0 z2 f, W' U' M+ t 对象(该对象有一个唯一的id, 一般称为sessionId)
# e' k. R7 `& a" g% z% ?- i 。服务器在缺省情况下,会将sessionId以cookie* m5 A9 S6 u M2 H5 g# R
机制发送给浏览器。当浏览器再次访问服务器时,; _( d) ~0 H! @. G/ R
会将sessionId发送给服务器。服务器依据sessionId
, ^9 K# z7 O1 O, ?2 U3 p 就可以找到对应的session对象。通过这种方式,
# P- Y, j. C9 U" {" z 就可以管理用户的状态。# A: G. P* ~1 M$ C1 T( k5 d/ q
b,如何获得session对象, B4 v2 R- J1 z/ V$ y
方式一:
/ t" a3 F) Z0 R6 b HttpSession session =
7 D+ U+ G- M4 ]: _; B/ I0 K request.getSession(boolean flag);
" ?4 j' j8 A6 C" g 当flag = true:! E# H% h' Q% Z# ^7 c q
服务器会先查看请求中是否包含sessionId,8 w- |, r. d% A+ p: D; i
如果没有,则创建一个session对象。: M0 b# K& @% Y* R5 S4 M
如果有,则依据sessionId去查找对应的
: l; A* Q: Z7 g$ `( g& d3 a session对象,如果找到,则返回。8 Y- ], t+ L' I/ S
如果找不到,则创建一个新的session对象。
# Y5 ^+ I9 Q, ]" d7 X8 n. j 当flag = false:0 ^! B: `+ [; Z4 z2 [
服务器会先查看请求中是否包含sessionId,
2 t( u; b F. i9 D 如果没有,返回null。
6 f! B" E% r p' W0 R) x 如果有,则依据sessionId去查找对应的0 f: I- n: Q7 F9 W- B
session对象,如果找到,则返回。
8 |3 E6 n! d# ^. `7 ` 如果找不到,返回null。
; R7 L0 d0 j& J1 | 方式二:3 c5 U6 Q2 ~$ L
HttpSession session =
7 _: S" s) j1 i- Z request.getSession();
) H1 C5 e, n" m* E8 D& A; N$ v. A 与request.getSession(true)等价。1 o/ F9 C% |4 E6 {% n
c,HttpSession接口提供的一些方法
. D, g( t. ^! N* O& J# O$ M0 a //获得sessionId。' M' c& Y1 [: q
String session.getId();
; q0 H& V& k2 r# p* [ //绑订数据3 ]$ U0 |- N- m
session.setAttribute(
# W# h/ z. @! q2 N5 @5 D. @ String name,Object obj);
. K' U. d* y' } k //obj最好实现Serializable接口(服务器
& C( B' p Q9 m3 t { 在对session进行持久化操作时,比如钝化7 J9 C0 _+ U( M8 Z% p
、激活,会使用序列化协议)。
( t8 F6 `- ]4 k% A8 i. Q9 r7 s Object session.getAttribute(String name);
$ n0 v. K* {* n k- @$ _ //如果name对应的值不存在,返回null。
0 X8 { b( L; h session.removeAttribute(String name);
7 O0 E. \" V4 v/ V2 ~$ K d,session超时5 | t' E5 l" g# [" K
服务器会将超过指定时间的session对象
) E0 O- u, d: ~ 删除(在指定的时间内,该session对象没有
c5 _* \: O& q |; j 使用)。
2 p7 ?1 L% R+ o7 u) j. o' K' t 方式一:& E$ G) b9 x4 q) E3 [. r
session.setMaxInactiveInterval(: S1 `$ w$ C; o' K
int seconds);
" z# v/ A' e$ L) { H1 W# o+ | 方式二:) v: c# K- m M4 F9 ~/ p
服务器有一个缺省的超时限制,可以 Z7 p9 L1 ^# C; g, w7 @& f5 h
通过相应的配置文件来重新设置。+ T) ~+ V( }: g' Z
比如可以修改tomcat的web.xml(4 {5 h1 t, ~7 K; q4 }
tomcat_home/conf下面)。
" L% J% W4 |9 w3 A, R <session-config>
F# c2 B% t1 u% q <session-timeout>30</session-timeout>
$ Q3 j& h, ^( @# e5 P* Z </session-config>
1 \8 x) p0 ], J, Z' _ 另外,也可以只修改某个应用的web.xml。
$ k) p/ d! t# ]3 I" q8 Z# F e,删除session
+ ]. s6 y% h& C$ M session.invalidate();
7 o" ]5 m, g9 J5 N( |5 H# u" l % w* l& Q& f" Y5 |& R7 Z$ P2 J
案例:
: B. g: u# z- y" T' R8 ?5 Z) L session验证+ d+ m& n: |0 u% d/ ]3 `9 q
step1 在登录成功之后,在session上绑订一些数据。
/ ~- E* d* [# I' K9 X& C 比如:) t. ?' z F4 v& k8 L5 n+ L. ?
session.setAttribute("user",user);
$ _1 W/ I1 {# V. a step2 在访问需要保护的页面或者资源时,执行6 o0 x1 s2 M9 l5 k& a* o
Object obj = session.getAttribute("user");) }7 S: N4 K7 n F7 [% ~
如果obj为null,说明没有登录,一般重定向到# _7 K8 J8 Q1 U% m
登录页面。! {# I4 x! B/ h# D8 n
|
-
总评分: 帮币 + 5
查看全部评分
|