该用户从未签到
|
状态管理% ^, X8 j; l6 ~/ y: V4 ] h
1)什么是状态管理
4 K5 Q4 a/ u' m5 s- H5 s* S1 m, b: E+ _ 将客户端(一般是浏览器)与服务器之间的多次7 c& A, [% s( Z8 Y" G+ g
交互当作一个整体来看待,即将多次操作所涉及的
1 o& P( X9 w H' f7 q 数据记录下来。. x1 m& }6 v E1 c: j9 ]
2)怎样进行状态管理* Z. e6 h, Q, r1 x h
第一种方式,在客户端管理用户的状态
3 |2 M A+ S) X6 q- T (cookie)。$ w1 c/ R. n. N8 ^+ E4 A) L, r
第二种方式,在服务器端管理用户的状态- n1 ] l' P X' w) k/ k
(session)。! P# f2 q e# q* L2 p% x) q
3)cookie, y8 a7 Z* {; s& B B* T% r
a,什么是cookie?
- W& b( o" Y6 O( h$ P 浏览器在访问服务器时,服务器将一些数据
+ i3 I4 a# I3 _% a* S 以set-cookie消息头的形式发送给浏览器。浏览4 z5 K2 Q4 f2 h4 f# e
器会将这些数据保存起来。当浏览器再次访问
- B) Y5 G2 B+ |* ?) H% d 服务器时,会将这些数据以cookie消息头的形式
2 Y% W" W/ M% i2 H 发送给服务器。通过这种方式,可以管理用户的
3 B( E3 p) v/ f$ J5 h$ D 状态。" e, v0 _' s' H$ |3 `) H) R
b,怎样创建cookie?1 i) w) W- c, s4 A4 l# i) N
Cookie cookie = new Cookie(String name,. E2 @) F7 v5 U( i$ l
String value);+ t8 Z: T/ h) S, u7 E
response.addCookie(cookie);
9 D- b* D3 ?2 H c,查询cookie! V# t' E9 f* K
//如果没有cookie,则返回null。
/ G9 R5 J8 H& w& A) F4 f+ _ Cookie[] cookies = request.getCookies();
* v4 W4 ^6 G0 g+ B1 ]- T" s String name = cookie.getName();/ j7 J4 _6 z' d% q
String value = cookie.getValue();. q F8 B; e. w! j& `: P! h
d,cookie保存时的编码问题
, i4 t$ q# q9 f7 w, \ cookie的值只能是ascii字符,如果是中文,, L- _. P# @6 q {! p
需要将中文转换成ascii字符形式。
9 y6 |% p, G- k3 J1 X! ^# q 可以使用URLEncoder.encode()方法和4 Q" {# R& N0 K! n, N: q
URLDecoder.decode()方法来进行这种转换。
; r L$ Q) X; P( z3 @- i" |. U e,cookie的保存时间- |/ ]- U% t' w8 c" n
cookie.setMaxAge(int seconds);: h5 L* J \( `( P) H' q( `
seconds > 0:浏览器会将cookie以文件的方式
! e3 G Q4 I1 N# E8 l1 g' c' O 保存在硬盘上。在超过指定的时间以后,会删除' X* ]9 ~" c+ `; i- u0 v/ k1 h, X
该文件。/ c7 R9 |" J* F
seconds < 0:默认值,浏览器会将cookie保存0 k" g5 v9 @8 [2 j
在内存里面。只有当浏览器关闭之后,才会删除。 \/ y" {0 b) `# I
seconds = 0:删除。
, z& w4 C& I* B! @7 k4 g) j4 S f,删除cookie
# c& e* [/ u! p4 v# o 比如要删除一个name为"username"的cookie。6 g. |+ o+ T, S6 f* E$ \" l) i$ ]
Cookie c = new Cookie("username","");
- m4 Q4 g; q; I5 k0 x: f5 Y c.setMaxAge(0);
# _2 f/ ]+ y; }! W response.addCookie(c);/ }7 c* j/ f5 h3 x3 I
g,cookie的路径问题
8 Y5 I0 S, t9 U' z8 F 浏览器在向服务器上的某个地址发送请求时," R- u2 F5 P/ n
会先比较cookie的路径与向访问的路径(地址)是
! j, @' M, }2 q 否匹配。只有匹配的cookie,才会发送。
5 o$ R9 S+ M$ _" V cookie的路径可以通过
6 Z# ?% L' n% n+ Y" ` cookie.setPath(String path)方法来设置。4 e& m- d$ j2 M0 ~
如果没有设置,则有一个缺省的路径,缺省的. I; w1 o0 G! A. q) B5 G
路径是生成该cookie的组件的路径。
- r+ B6 q2 N7 @8 ~/ e4 D7 T( S 比如: /appname/addCookie保存了一个cookie," w* q* Q3 |" [& p0 J9 C
则该cookie的路径就是/appname/addCookie。
2 S. _3 Q8 b. B* H. p; U! R. ^
9 r- o: p. R' i m/ T' L 规则:# v2 R( x3 K5 D& p
cookie的路径必须是要访问的路径的上层目录
5 G9 |8 t$ t4 _6 @$ `& L& S, M& f 或者是与要访问的路径相等,浏览器才会
6 A5 u# A6 E) e 将cookie发送给服务器。 J, o. ^* n4 ]* n5 Q' C8 D6 R5 Q8 f
3 |3 y+ e% a, w( T 一般可以设置setPath("/appname"),表示访问4 { q# k; ?( Y: n/ @5 D* _
该应用下的所有地址,均会发送cookie。* @2 f7 u/ C- y s
h,cookie的限制1 G" U$ p! o8 n; o4 }' M
cookie可以禁止
; ^4 e: _, y3 i+ j, A3 M& Z cookie的大小有限制(4k左右)
: ~5 u* E2 i1 H, s/ s cookie的数量也有限制(浏览器大约能保存300个)
( y% k8 z6 w& T9 z" X cookie的值只能是字符串,要考虑编码问题。
/ C, Q" L* D/ y, w7 W; q6 O cookie不安全
) @7 i5 D7 O2 K4 M& P) ^% N* M 练习:. Z j% W6 [ b5 p$ E# @$ j) Q
写一个Add_FindCookieServlet,该servlet先查询8 f! @6 {; `% f# ]
有没有一个名叫name的cookie,如果有,则显示! R9 G" F" T' c% X: {
该cookie的值,如果没有,则创建该cookie(/ _% u4 g5 I" s
cookie的名字:name,cookie的值:zs)。
; ~6 S' a+ I, _# f
8 P& z. A5 r( P- |) r7 E- l' b
6 i# U, T/ {: M5 o" D! Z 4)session 1 i$ w' T1 Q5 i: L' R8 T0 v5 ]
a,什么是session?
- x: s8 D2 i' H; v1 d) P5 X 浏览器访问服务器时,服务器会创建一个session
5 |- e2 t" i' o+ I. E 对象(该对象有一个唯一的id, 一般称为sessionId)
" N. E" L4 W/ t5 M) | 。服务器在缺省情况下,会将sessionId以cookie
1 U4 Q0 a6 Z1 \& e9 A! d 机制发送给浏览器。当浏览器再次访问服务器时,
+ }! z. T( w% H+ X C5 z 会将sessionId发送给服务器。服务器依据sessionId) I; k, Z0 ~" B+ p- x
就可以找到对应的session对象。通过这种方式,: J4 q" @/ W w; T0 y
就可以管理用户的状态。4 G" e- m0 e8 O, K. t! G7 o
b,如何获得session对象
- q" q. ?6 Z8 w4 Q7 Y 方式一:+ I) G x( }2 ~8 c; X
HttpSession session = ; j0 O) x+ O! O$ x+ j, S2 f! K6 U
request.getSession(boolean flag);
$ x$ |+ | R; Z 当flag = true:5 o+ o. ]! Q$ @2 L
服务器会先查看请求中是否包含sessionId,
5 K- h& k6 q) s 如果没有,则创建一个session对象。
2 H& W' W. J) z% _ 如果有,则依据sessionId去查找对应的) x) H, `. j2 _1 G: t& m
session对象,如果找到,则返回。
6 t" e1 Y& }5 N2 k5 k/ n 如果找不到,则创建一个新的session对象。
1 k9 {- _1 t/ w+ r; }) o1 e 当flag = false:: Q# r) K& K l& T5 D
服务器会先查看请求中是否包含sessionId,
e8 ^7 J. p$ t, e- g% J 如果没有,返回null。
( D9 A( ?: R8 _1 p 如果有,则依据sessionId去查找对应的8 ]& V4 n6 M. w' y1 k( b
session对象,如果找到,则返回。: J5 ]2 h' c( T0 Y" L( G$ G& I) `
如果找不到,返回null。7 H9 U( P$ D5 P \/ i
方式二:$ R: T$ C$ b) p0 P* P2 N
HttpSession session =
- P- T6 \3 m+ I4 P' {% l request.getSession();
- V; P& y$ k# m6 ^ 与request.getSession(true)等价。; o4 S% e. I# U8 t" f S/ {
c,HttpSession接口提供的一些方法
0 t. ~* M/ H6 U/ b' ? //获得sessionId。# w& [: U! s3 N, t! n: C/ j
String session.getId();
- V+ W) l2 `; v7 s //绑订数据
, c1 Y5 @# B; _, s2 \4 \ session.setAttribute(
/ D5 Q4 S* C; K6 f String name,Object obj);
2 [ ~- a5 `# v //obj最好实现Serializable接口(服务器& E# G' N7 V: }
在对session进行持久化操作时,比如钝化
2 e& Z8 B+ g* d 、激活,会使用序列化协议)。
0 D* b: G9 Y/ E9 c- z Z Object session.getAttribute(String name);
- h( u, m- D# w& A6 V) }& g M" u% I //如果name对应的值不存在,返回null。4 ^/ g( l8 s! D8 A8 v. P( o
session.removeAttribute(String name);
* L" C& U6 b1 C6 S5 C d,session超时 N# c9 w! g! E' k
服务器会将超过指定时间的session对象" r& A2 Q, O) W7 h5 X5 e' d
删除(在指定的时间内,该session对象没有- X% p. G1 X5 J! n$ {" B
使用)。/ J1 K) [3 h1 X5 Z: r
方式一: ]( L1 H' j; c1 l
session.setMaxInactiveInterval(8 G0 [, T6 @( S# B" M
int seconds);
0 A, V) G! `5 T4 w# E1 d; d! O S 方式二:
! }( j7 [, L8 T! r/ s& \8 D 服务器有一个缺省的超时限制,可以
9 g1 T1 L9 u& N# U( M2 ?1 H 通过相应的配置文件来重新设置。( H [- X8 y- L( Y( h, m# d
比如可以修改tomcat的web.xml(
$ y0 [( r u7 G9 _8 W0 s tomcat_home/conf下面)。
. a4 \4 c# Z7 K6 }7 A; K' ] <session-config>2 l) S7 ~. K% q
<session-timeout>30</session-timeout>9 j- h3 n5 R3 Q; J- R
</session-config>4 @: V0 k! C! w7 x+ n: S
另外,也可以只修改某个应用的web.xml。
2 O& Z6 s) L7 i e,删除session# a4 Y) y. |5 F" C, s9 A M1 A, Z& p
session.invalidate();& n- I1 v& X, A
0 L% D$ }" }' j
案例:
3 \3 D% u }3 [# N9 r9 w session验证/ f3 r; D/ Q: O# \
step1 在登录成功之后,在session上绑订一些数据。- N# X& }9 p# E4 F `
比如:' H( Z: f L; V# X/ q0 H
session.setAttribute("user",user);' y! Z: l' e# }* P# l6 z
step2 在访问需要保护的页面或者资源时,执行
9 [1 Z& M5 b! Q1 b+ A7 E) `8 X) | Object obj = session.getAttribute("user");
% m9 f' E& e3 E! f j; ^4 e 如果obj为null,说明没有登录,一般重定向到
; w" f5 |* k) b! H 登录页面。; l0 |6 E* k d! N
% S1 v- V& J" B' H. \4 T |
|