该用户从未签到
|
2、状态管理0 b; L! h% r* ?: w. l! I
1)什么是状态管理
$ i) V; }8 w6 D. t2 ^* J 将客户端(一般是浏览器)与服务器之间的多次
( m* n" n6 m B 交互当作一个整体来看待,即将多次操作所涉及的
0 S3 p) z! Q q% c2 ^ 数据记录下来。& E! e+ m3 X0 {5 q1 B q' r1 b
2)怎样进行状态管理
9 T% U/ {+ \( W& Z. z! x/ C 第一种方式,在客户端管理用户的状态$ y' L; N% I3 d) C
(cookie)。
/ w4 F+ q- L0 n* s: S G. J 第二种方式,在服务器端管理用户的状态5 w6 R2 ^: x! K: [
(session)。% w2 C- s: \ o1 `
3)cookie
( a8 q5 v- H% ~& w8 b a,什么是cookie?4 H% \) D& e. |5 T7 N$ L& j
浏览器在访问服务器时,服务器将一些数据& R6 X* K3 E* {' D
以set-cookie消息头的形式发送给浏览器。浏览) s! C) j X* {5 O) F0 U6 f# N
器会将这些数据保存起来。当浏览器再次访问/ K. i" I! V% V/ s$ j% _$ D6 S
服务器时,会将这些数据以cookie消息头的形式
) c: f4 \7 b7 V 发送给服务器。通过这种方式,可以管理用户的! w- P3 Z& d' i! i) h/ N) T2 N u# L# t
状态。+ _9 D7 c) ^) l
b,怎样创建cookie?
2 p! Q" U! C: y4 Q Cookie cookie = new Cookie(String name,
: c+ {! j$ s4 t( V4 Z String value);6 {; x. R( {0 D3 r' s1 X
response.addCookie(cookie);( D! x) e* q' a0 w
c,查询cookie
, Q& B: L1 @0 w0 c5 U* \3 a //如果没有cookie,则返回null。
8 g; e" C: b: [) ^ Cookie[] cookies = request.getCookies(); f3 g6 _3 r& Y4 Q6 C9 v& Z
String name = cookie.getName();+ _: h. E0 q2 s p9 I p
String value = cookie.getValue();- c6 ]# ?$ ~7 V; k/ H7 {9 n
d,cookie保存时的编码问题
6 x1 S6 w8 F) N cookie的值只能是ascii字符,如果是中文,+ S% _: ~5 F2 |) K+ K
需要将中文转换成ascii字符形式。3 X+ D3 F+ a; n; T
可以使用URLEncoder.encode()方法和, f! @' L2 t: T- T2 z& H7 p6 H
URLDecoder.decode()方法来进行这种转换。
. s$ Y# _9 R2 p3 ~( o9 ] e,cookie的保存时间2 a1 O1 I3 h; t4 y0 I: p
cookie.setMaxAge(int seconds);
# Q( k! B; D9 S seconds > 0:浏览器会将cookie以文件的方式2 P: L K ^# I y( ?
保存在硬盘上。在超过指定的时间以后,会删除
& S8 g: ]5 G& x1 E h 该文件。
! Q9 s- Z; N" X; f/ N) j( b seconds < 0:默认值,浏览器会将cookie保存 T8 t& p. ^6 P o* H
在内存里面。只有当浏览器关闭之后,才会删除。
% m" b( g) g1 L! D1 p h seconds = 0:删除。6 B4 s* r j1 b+ I
f,删除cookie2 n F& J; l/ Q" |' e
比如要删除一个name为"username"的cookie。* y& u3 g& j9 }# X
Cookie c = new Cookie("username","");2 K4 d7 @. D( ?$ A4 I: m# s
c.setMaxAge(0);
8 q! i* s6 y1 y& F* b; B$ A response.addCookie(c);1 X6 V) h" u% s9 H4 t; ]
g,cookie的路径问题
% W* U1 I, g, z s8 i% @- J 浏览器在向服务器上的某个地址发送请求时,* [- O) i5 l- w5 |% V0 \$ s
会先比较cookie的路径与向访问的路径(地址)是) ~; M, G8 [/ N/ p) ^: \2 ]
否匹配。只有匹配的cookie,才会发送。% q! n+ i4 p J1 R: ~
cookie的路径可以通过
( B* ^9 l) J9 ~9 n( M0 V cookie.setPath(String path)方法来设置。
1 U+ c9 S1 ?4 H! ?: Z* ]; z& p7 s 如果没有设置,则有一个缺省的路径,缺省的9 U' G7 t. ^# I# j. F. \& _" ~
路径是生成该cookie的组件的路径。; M" i1 N9 O( M+ D
比如: /appname/addCookie保存了一个cookie,
3 N2 s) E% b2 K2 y; W- } 则该cookie的路径就是/appname/addCookie。" J- T9 ?8 h F2 G7 q
! g6 u8 k7 m* ~ 规则:
/ p2 d, w% y, m0 u5 {# B cookie的路径必须是要访问的路径的上层目录) W7 V: m, I: |
或者是与要访问的路径相等,浏览器才会! J, i( q, i6 I! K
将cookie发送给服务器。, E- g3 y& ?3 w- o% t# J& k: h
5 f' {/ T2 M' g9 W8 R% e6 M4 i* C
一般可以设置setPath("/appname"),表示访问
8 ?* Q2 k: G' {/ F: }5 c 该应用下的所有地址,均会发送cookie。$ K' S+ j) j, {) [1 e5 _/ u
h,cookie的限制3 _# @( s+ }' _
cookie可以禁止
3 n2 R9 Z* N* j x5 G2 {6 n$ v5 M( o cookie的大小有限制(4k左右)
7 h: y4 J6 c: c9 e" {1 C" t! E cookie的数量也有限制(浏览器大约能保存300个) 6 }6 U" H- F- \1 x" Q; h; M+ o
cookie的值只能是字符串,要考虑编码问题。' ]" y/ b- H# L+ @2 D
cookie不安全
+ X9 b' [" N8 f 练习:
; |9 c) B0 F! k: l' G 写一个Add_FindCookieServlet,该servlet先查询
. l5 ?% b, S( x$ x/ Y, u 有没有一个名叫name的cookie,如果有,则显示; G3 [4 \- L( l; M( v! \) m
该cookie的值,如果没有,则创建该cookie(2 Q. w4 ^* {7 M# A
cookie的名字:name,cookie的值:zs)。$ ~: y! ]# z+ Y1 i2 G
7 X* Y2 r {! t) L. N7 ~
( _1 P# [; v3 L4 G7 e. g% N 4)session - l7 ?' V4 g# y& d! o$ H# i7 ^) F5 _+ n
a,什么是session?. _/ R$ T9 n& H: o2 v! _0 F
浏览器访问服务器时,服务器会创建一个session. o" \, ~4 e3 O; b+ h& O
对象(该对象有一个唯一的id, 一般称为sessionId)9 F- X* ^, |( C m. P8 R
。服务器在缺省情况下,会将sessionId以cookie4 S: L. o: `1 [4 [. x
机制发送给浏览器。当浏览器再次访问服务器时,
; L1 D" W2 K g 会将sessionId发送给服务器。服务器依据sessionId8 n/ A l" g: i# B2 e) c: E0 z, f
就可以找到对应的session对象。通过这种方式,, J$ t& E: C8 ]* _. S$ Q! Q
就可以管理用户的状态。8 E+ w* Q# S$ n/ W6 v
b,如何获得session对象
1 j5 M* D/ ^0 n$ K- e 方式一:
: U0 u; R0 o8 u; }, m6 j1 t- ^7 Q HttpSession session =
& O, R" I, e3 s7 y3 t( P request.getSession(boolean flag);
P. M, E5 h/ ^% o. R* M. X7 V 当flag = true:
* M+ d, P* |5 C 服务器会先查看请求中是否包含sessionId,
5 G! B# v. m$ e" s2 L' Z0 o 如果没有,则创建一个session对象。
8 g* Q% |6 s% e/ {3 y% r! H/ Q 如果有,则依据sessionId去查找对应的
* Q2 }. ?! o% @# @2 C8 v+ s session对象,如果找到,则返回。
. m7 s2 h6 \+ `! M 如果找不到,则创建一个新的session对象。
* c: j3 J; Y7 C% R+ c. M" ? 当flag = false:
0 | Y# S/ T( V* I! U" [ E1 M 服务器会先查看请求中是否包含sessionId,3 l `7 R' X$ |8 }2 T
如果没有,返回null。
4 A% m# a" W! q" m 如果有,则依据sessionId去查找对应的7 I5 p. r3 D: g4 N
session对象,如果找到,则返回。 r# c, [, l" O, g& D
如果找不到,返回null。0 a m9 z& C& f/ H7 Q {/ C; ~
方式二:& L" B2 |. E( d4 k
HttpSession session =
4 n$ l( H% B' u( o- Q0 f+ l+ m' T+ u9 U request.getSession();5 t) J# J' i3 \( p8 i0 c% g. D+ w
与request.getSession(true)等价。# d7 n% E% S2 {" U! g
c,HttpSession接口提供的一些方法
& {& Y2 @# V: V6 R) ^ //获得sessionId。) v b: e" j. i
String session.getId();' T: N( l% u h. D) Q/ k& [( g: n
//绑订数据. R ^9 ^- \9 X
session.setAttribute(
* N4 }6 |1 Z$ n1 F* U String name,Object obj);
& J% t5 u- `9 E S //obj最好实现Serializable接口(服务器" d; y1 p' S6 H7 T/ N2 [
在对session进行持久化操作时,比如钝化
S2 M' R4 U n! |* U/ t 、激活,会使用序列化协议)。6 d, ?. e, [5 ^/ K6 Q
Object session.getAttribute(String name);
* U k; [" a* ?' m+ G: T //如果name对应的值不存在,返回null。8 ~5 z# Z3 F0 H8 u( J2 D
session.removeAttribute(String name);8 D& e1 A* V& E2 N" E0 V
d,session超时
, x) P# d3 I) j; L 服务器会将超过指定时间的session对象
* m$ w3 g: Y/ F% t* W9 V 删除(在指定的时间内,该session对象没有
- P" U& a* a2 l/ C, G 使用)。% J1 P; ^. ~& ~' V, N& p
方式一:9 A* t; r& M4 Q( w& r8 i
session.setMaxInactiveInterval(8 L% P1 l: s& T2 {- I8 P+ [
int seconds);: Y4 G) J" {3 q* ^6 j# ~3 ^" L$ k& E
方式二:
/ Y$ A- ^$ U/ ]$ ^' x. s- n 服务器有一个缺省的超时限制,可以. Z* L$ F: E% B' M
通过相应的配置文件来重新设置。
5 w, D* i/ q4 m% {3 T9 D 比如可以修改tomcat的web.xml(
- i! I4 C o1 r3 o+ i$ b6 N, q tomcat_home/conf下面)。
9 d* e$ u2 r) T3 U <session-config>
7 D. O' E- Y: f <session-timeout>30</session-timeout>
1 W4 O; b9 K) f- w </session-config>
2 K0 ]3 ~3 }4 { 另外,也可以只修改某个应用的web.xml。
+ a9 D$ @# Z: ?2 T3 d6 I N' S e,删除session
% Q) C& K: I" G: [2 o7 K) a1 S& h session.invalidate();& z w+ `+ Q- @, G
5 L- m) T1 e6 U
案例:
; P3 s3 [. L2 e/ x7 ]$ c5 H, [ session验证
* j8 A9 z. z, d# U: k( \ step1 在登录成功之后,在session上绑订一些数据。
9 ^% C0 Y1 h- h0 \+ Z: I 比如:* C( L3 j0 c+ f* Q
session.setAttribute("user",user);8 T' V; u9 W2 ~6 N
step2 在访问需要保护的页面或者资源时,执行/ t% U$ n6 E9 }# W8 P
Object obj = session.getAttribute("user");
. U/ `- j4 w- t3 m- Q& I) Z/ n 如果obj为null,说明没有登录,一般重定向到
g, _" Q9 g, P d/ j& E5 m 登录页面。" t8 j; r7 R0 G6 k
|
-
总评分: 帮币 + 5
查看全部评分
|