该用户从未签到
|
2、状态管理) j! o- z3 f. e* j3 H6 {) G
1)什么是状态管理* n/ N' A/ Q8 d ?% T
将客户端(一般是浏览器)与服务器之间的多次
( R9 e# Y( S* q% Y: Y 交互当作一个整体来看待,即将多次操作所涉及的1 t0 w3 P4 A" m7 D' Q
数据记录下来。( F! z' C: `/ n) L4 W8 B1 U& H
2)怎样进行状态管理
, U+ u. R: C+ M 第一种方式,在客户端管理用户的状态7 B" J6 R9 w, N1 Y6 u- J. y/ l0 `
(cookie)。4 C. b! H6 Z! ^, i2 m% z
第二种方式,在服务器端管理用户的状态) @* F. B1 ?% k8 ?) |. k" Q
(session)。# U' a# g2 m$ w* `/ h, k) c$ Q- w
3)cookie
* I$ I! Z+ k( A" J7 [+ G a,什么是cookie?
: }. M! f7 C a 浏览器在访问服务器时,服务器将一些数据% y% |+ H$ a' ~) v3 Q1 m
以set-cookie消息头的形式发送给浏览器。浏览; W0 g3 h; P( L+ P _8 y& K
器会将这些数据保存起来。当浏览器再次访问
% x. N/ [" ?5 { V4 C$ u 服务器时,会将这些数据以cookie消息头的形式
* u; B" z/ c& t) J6 t, k! _, Z1 p1 M 发送给服务器。通过这种方式,可以管理用户的6 s V# p# p- |/ |# d$ b1 B" d
状态。
7 \& O/ e7 A$ ?$ |+ j s b,怎样创建cookie?. c! I+ q; ~/ c/ ^
Cookie cookie = new Cookie(String name,
$ m* Q: z- r1 D* q8 @# F% K String value);) N& G4 d+ r8 }8 ~$ M3 J
response.addCookie(cookie);
}; `& P4 I, \2 q0 C# D1 u- ? c,查询cookie
! c& X! D3 U C8 w //如果没有cookie,则返回null。# [5 @* Y* k1 a `3 Z% j9 p
Cookie[] cookies = request.getCookies();
+ R; r9 h& @: p1 p8 N$ T' O String name = cookie.getName();$ w$ ~$ y/ V _) b
String value = cookie.getValue();+ V: e0 c! J+ D
d,cookie保存时的编码问题
1 l+ Y/ Z- n$ L y Q" Q7 _ cookie的值只能是ascii字符,如果是中文,
& b6 N! v- f7 q, |' Y/ b5 g9 u" d 需要将中文转换成ascii字符形式。7 J5 x6 {, o; U- m
可以使用URLEncoder.encode()方法和
, ?* o* Q( k/ R URLDecoder.decode()方法来进行这种转换。1 z* Y' O/ M$ u9 R
e,cookie的保存时间
2 W0 T3 S( |+ A1 w: h9 t% s6 l cookie.setMaxAge(int seconds);
) s2 K/ M; W. w, P seconds > 0:浏览器会将cookie以文件的方式, q H2 b0 ~( w) y/ }0 x1 h
保存在硬盘上。在超过指定的时间以后,会删除& ]: C Y6 X2 d' e y
该文件。, I8 I- y4 ]- k" Y
seconds < 0:默认值,浏览器会将cookie保存, z; `$ y& r# U) z
在内存里面。只有当浏览器关闭之后,才会删除。. v% A( P" I) G$ d ~
seconds = 0:删除。# z0 @% U w" C6 F- i
f,删除cookie& } R7 H- j( f) o# M7 Q3 `) X
比如要删除一个name为"username"的cookie。* U6 {. ~7 e( R4 P8 S7 [- H
Cookie c = new Cookie("username","");- M# e3 q8 I! a- h
c.setMaxAge(0);! @) Z/ v' Q+ [2 t
response.addCookie(c);; r* }! |% u/ |( V8 E
g,cookie的路径问题' F( u/ |) | v1 c. E i6 p9 @
浏览器在向服务器上的某个地址发送请求时,
2 s0 P7 {7 o, s2 N; \1 ?/ v) x 会先比较cookie的路径与向访问的路径(地址)是
9 d! e' D2 a$ v# J( v. N 否匹配。只有匹配的cookie,才会发送。. p& T' o/ z* J$ V, p* J
cookie的路径可以通过5 y- Q" Q; l7 N; o! r& B
cookie.setPath(String path)方法来设置。
& W4 W% o* N3 E0 f$ j 如果没有设置,则有一个缺省的路径,缺省的
% `. U9 Z3 V' b 路径是生成该cookie的组件的路径。
& k% t* V& s0 _ 比如: /appname/addCookie保存了一个cookie,+ }7 g' M2 Y! _. m& ?8 i* I) u* w
则该cookie的路径就是/appname/addCookie。2 l) K3 ?0 d: ~- ~
% X$ |0 E9 {+ {6 f) y0 J0 K3 H 规则:8 M/ {3 C/ H. n" x/ U4 `+ m' Y
cookie的路径必须是要访问的路径的上层目录' i' H- |/ v9 G; A1 H* @- K
或者是与要访问的路径相等,浏览器才会% _- A) c9 U4 i' y! U+ k7 |& b
将cookie发送给服务器。
2 i3 Q3 i' ]* y* S; |/ J* N% R ' n2 G+ c; W) Q7 G
一般可以设置setPath("/appname"),表示访问7 L; C% f: v) S# \8 p6 l
该应用下的所有地址,均会发送cookie。& k% Q+ P" t/ Q* e1 |# [* U
h,cookie的限制) O" l. v. O+ D( g7 g8 H
cookie可以禁止
- v( O0 k \# Y0 U3 X cookie的大小有限制(4k左右)- I0 B( H9 |0 }5 m8 p! {
cookie的数量也有限制(浏览器大约能保存300个) ' ^* ~* E0 Y, G6 a6 v
cookie的值只能是字符串,要考虑编码问题。8 k7 n) r1 m) G& K
cookie不安全: j8 @: q. L" b% D! ]* V' L
练习:
$ J# f+ A- i( F" p" x2 f 写一个Add_FindCookieServlet,该servlet先查询
5 k: f1 F6 l+ A% |& i' Y1 d3 t4 L8 \ 有没有一个名叫name的cookie,如果有,则显示
1 ~4 w6 e$ q1 v3 @* p 该cookie的值,如果没有,则创建该cookie(, K8 x' E- L7 A* t4 }1 k; t+ C' c
cookie的名字:name,cookie的值:zs)。9 t5 _ F4 l# J" H) I
# w' s" M( D2 n! q+ { S- x0 W
. g Q: Z+ z$ E6 U; \4 u 4)session
2 \7 W9 ^2 [; E a,什么是session?9 d- x& @: j! X+ E1 {
浏览器访问服务器时,服务器会创建一个session
- L2 O# Q! B$ J' p! z; h& ? 对象(该对象有一个唯一的id, 一般称为sessionId)" k' B( S/ m, e( v6 ~
。服务器在缺省情况下,会将sessionId以cookie3 u* T3 n4 L8 n
机制发送给浏览器。当浏览器再次访问服务器时,
8 r8 ?5 t3 V1 F1 @% y 会将sessionId发送给服务器。服务器依据sessionId7 }+ m+ t0 N0 Z2 l9 U' ~
就可以找到对应的session对象。通过这种方式,; W, ^# d+ K) Z, {+ v
就可以管理用户的状态。3 E/ x2 ]1 _2 s1 }
b,如何获得session对象- a) _# w: G1 w
方式一:2 F b& G. C f m3 i
HttpSession session = / C% g: ~' \ }- W5 h; I
request.getSession(boolean flag);
5 W. s3 s/ D- a' j6 L5 `" \/ T 当flag = true:
! h* z' ]) A d 服务器会先查看请求中是否包含sessionId,
* e4 t- c4 ~* u: Y: B 如果没有,则创建一个session对象。
- C- o# l( n- \. i/ u4 D4 o9 O4 y6 o 如果有,则依据sessionId去查找对应的: x$ f& f% c0 a+ H
session对象,如果找到,则返回。
, i8 j' G0 v3 N+ ?* |% p, g* n 如果找不到,则创建一个新的session对象。
3 U! [2 s/ M9 D 当flag = false:
% j% D v, J# r3 }! U 服务器会先查看请求中是否包含sessionId,* s4 N4 C3 g& i i3 I4 y
如果没有,返回null。
4 C- Z' g4 f& n 如果有,则依据sessionId去查找对应的$ L2 e4 n, i2 u7 s9 C
session对象,如果找到,则返回。" Q( N5 a( y' a% E, a. p7 c0 Y
如果找不到,返回null。
4 K3 f# v1 \) X' |- U9 { 方式二:
' _( c8 a; ^+ e, C6 E5 R HttpSession session =
/ c3 @& d& J$ W2 [ request.getSession();& |( t! n8 h* B( M [( p/ X7 B
与request.getSession(true)等价。
6 X6 _; `3 D) `0 ~ c,HttpSession接口提供的一些方法
' H5 r3 U, o' h //获得sessionId。% I3 ? k/ n- q) j& e
String session.getId();& K4 M* i, N" d' [# n
//绑订数据
! h. E8 N. _, A session.setAttribute(
/ q: j. L! l1 N$ Z) W String name,Object obj);- C1 \) E8 ` g/ ~# `/ e# F
//obj最好实现Serializable接口(服务器 J; t" D0 S0 R4 ]9 {
在对session进行持久化操作时,比如钝化
/ ?. O, F( B& B: A5 ^. S3 ~" @6 C: { 、激活,会使用序列化协议)。; B8 ~2 A( r& b% U) ]) s H; u% `$ x
Object session.getAttribute(String name);4 D u$ Z9 ?" p
//如果name对应的值不存在,返回null。
5 h7 V+ [& p) Y9 R- M session.removeAttribute(String name);2 J( K7 n- x N% y q7 b
d,session超时( Z( C l2 `, x9 t
服务器会将超过指定时间的session对象' r6 c0 O7 V# ^' p, f
删除(在指定的时间内,该session对象没有( h {( d8 n% N; g% |% H
使用)。, f i$ {% o' T, H4 n9 k* X
方式一:
4 }$ N% X- N. j# h5 S" {. I. ]; P2 N session.setMaxInactiveInterval(
6 q" @3 F3 i9 [9 Z0 k+ G* F {/ S int seconds);
% L, m' v" o9 J4 P/ [' E 方式二:
6 N# u5 J5 L/ D 服务器有一个缺省的超时限制,可以
7 y6 K" ~* F T: f/ a 通过相应的配置文件来重新设置。
( n; I" J% e- P% F9 T# q 比如可以修改tomcat的web.xml(
- ^# n6 L1 r4 D& _( d tomcat_home/conf下面)。
/ a X1 y! B& X& E( q0 M$ ~ <session-config>
, H9 `9 }1 a* i1 D <session-timeout>30</session-timeout>
/ Z7 Z. X+ s' I! @! K8 k5 w- `- `6 s </session-config>
2 S4 I7 V0 w; j; ]6 [ 另外,也可以只修改某个应用的web.xml。
; z+ P L2 C2 w e,删除session
^9 A* q! s; ^( k! a+ Q7 N session.invalidate();/ v* }6 r: c% o
$ z. X# [" B% l. x
案例:. o8 _. Y0 f# s3 Z# }
session验证* i6 \' t/ F0 N) A* Z9 ]5 h
step1 在登录成功之后,在session上绑订一些数据。
K: @- |8 Q9 F! z7 S6 S 比如:
* g+ r8 X1 c1 G6 t: p+ N/ N session.setAttribute("user",user);5 W/ D9 r/ ~: S) o
step2 在访问需要保护的页面或者资源时,执行4 |4 z# j: i0 m+ [: X0 ?; E
Object obj = session.getAttribute("user");
( g) A" c: {/ G% P4 G" v1 m3 s 如果obj为null,说明没有登录,一般重定向到+ _; m( n; P# C7 Y
登录页面。
! R5 G4 s% _0 m, H. ?8 G0 I2 E4 a |
-
总评分: 帮币 + 5
查看全部评分
|