该用户从未签到
|
2、状态管理
) m) u2 S: l1 T1 @: g 1)什么是状态管理& ]6 g6 d% j r7 F, j
将客户端(一般是浏览器)与服务器之间的多次
# ?: |5 ?, ?$ n' E7 ? 交互当作一个整体来看待,即将多次操作所涉及的
6 ]; {, \1 v5 l9 j/ O# \ 数据记录下来。3 c: w# X% f5 E6 u. U- J! o
2)怎样进行状态管理6 Q6 s6 b4 ]. E& z$ E( l6 _
第一种方式,在客户端管理用户的状态
; M% r* S8 J3 c( Q- `/ U* ]7 i (cookie)。
# i! E! Y+ k$ a! G8 X2 ~ 第二种方式,在服务器端管理用户的状态
+ x2 t" a" K! r8 D) s! J% O6 F" Q( n (session)。( H o, L. M. j3 |. |1 x/ z: R
3)cookie
/ V4 I/ W$ ?+ |, z a,什么是cookie?- a5 u. l5 I, w# W* Y% I
浏览器在访问服务器时,服务器将一些数据5 @/ }- I) S2 a. c: x1 i+ n
以set-cookie消息头的形式发送给浏览器。浏览
# N$ r0 H& q1 f/ w; e% y# e 器会将这些数据保存起来。当浏览器再次访问
! ~, r1 d4 Y' n3 K& i% b% E( X 服务器时,会将这些数据以cookie消息头的形式8 F2 y/ N9 X" U* Q4 p8 P& R
发送给服务器。通过这种方式,可以管理用户的
8 C: Z( S# _% e 状态。+ j$ T/ j, ^' Z6 _
b,怎样创建cookie?* o+ j! u" U% r. y. f5 `
Cookie cookie = new Cookie(String name,, Q9 v P$ K6 x' |
String value);
5 l* s1 J# }* x- C# y6 J- { response.addCookie(cookie);4 m! l: r; t8 L: m+ p
c,查询cookie3 Q) n0 A& h* [, j) Q. S
//如果没有cookie,则返回null。
4 Y$ g) P! o" y; C: h8 K4 _2 h Cookie[] cookies = request.getCookies();9 W, ] m8 l" Y
String name = cookie.getName();
$ J+ N3 y0 A; P8 L8 a: \5 ^ String value = cookie.getValue();6 x1 U; _5 P! f! K1 ]% G3 H* a2 p# E( l
d,cookie保存时的编码问题
- _. S1 R. R. m3 T* Q cookie的值只能是ascii字符,如果是中文,; e: L8 ^2 ?; K/ t! h
需要将中文转换成ascii字符形式。, s+ x- a& d# O& ?; w) _
可以使用URLEncoder.encode()方法和
^; |7 A; z. F" i& P- _ URLDecoder.decode()方法来进行这种转换。3 b* T0 V1 T+ {5 o- }0 d/ Y$ Q, J
e,cookie的保存时间, d. i0 M+ Z4 A4 T4 ^
cookie.setMaxAge(int seconds);
& h+ t/ e/ G; Z; W C seconds > 0:浏览器会将cookie以文件的方式
1 S8 R+ q" c8 b. H6 X: _6 H 保存在硬盘上。在超过指定的时间以后,会删除1 _3 ^- T8 k& A+ C' h
该文件。8 e; t3 T" c6 {" f# t* N& j: Q
seconds < 0:默认值,浏览器会将cookie保存
; ^: z1 P& a# V 在内存里面。只有当浏览器关闭之后,才会删除。
* l/ s v) E, p+ {* |( s. I: n seconds = 0:删除。# L4 Z( ~+ Y6 m% l6 m3 ]* R( i/ J3 n
f,删除cookie8 b( q1 m6 y j+ n7 N; V
比如要删除一个name为"username"的cookie。
6 |" q' o1 J+ z4 q2 _ Cookie c = new Cookie("username","");
$ b0 G) e" ?# {7 A, W: Y2 U c.setMaxAge(0);* r: A+ P# v* ]0 h+ O. G, E/ a
response.addCookie(c);0 @& k$ ?/ g% p- z
g,cookie的路径问题
2 B, ]0 N; F! a 浏览器在向服务器上的某个地址发送请求时,+ m" K- h9 J* ^; f0 L3 F% F6 x
会先比较cookie的路径与向访问的路径(地址)是
* L( U5 s' j3 F/ D) e 否匹配。只有匹配的cookie,才会发送。
, [5 ], I' d* o$ w4 b cookie的路径可以通过
, ?. L" I. p8 A/ d cookie.setPath(String path)方法来设置。% t- b+ y1 D. `7 w0 V
如果没有设置,则有一个缺省的路径,缺省的1 p. D/ u5 G& w2 t: o
路径是生成该cookie的组件的路径。- _- N8 S y8 o% M4 N9 ?4 Z
比如: /appname/addCookie保存了一个cookie,
3 a6 \" }" D$ S6 |) c9 w* ~" V/ }; S 则该cookie的路径就是/appname/addCookie。1 I; B& c# c0 h9 x# E$ x9 t
8 c3 E3 N Y0 M. r- \! {, Q, N
规则:7 H8 Y7 A5 q7 {% u9 e
cookie的路径必须是要访问的路径的上层目录
8 r2 i- G% B) J o0 {* F6 U' S 或者是与要访问的路径相等,浏览器才会/ Q& T! |4 ~: i& V* H0 ]
将cookie发送给服务器。# i0 ^8 T r) e2 d
& p. e4 ~/ Y# L1 q
一般可以设置setPath("/appname"),表示访问
. r% ^; |3 O6 e) L* e) W# K 该应用下的所有地址,均会发送cookie。2 r7 M+ A, m, F
h,cookie的限制5 j! A! ^9 |4 M/ D) j, L5 |$ U
cookie可以禁止
; @4 B2 S& \( {# _8 P) I& T cookie的大小有限制(4k左右)
v! Y: Z. ^2 `+ L1 M: g& r" c cookie的数量也有限制(浏览器大约能保存300个) . s: z) \( Y v( {5 n- Q) L7 m
cookie的值只能是字符串,要考虑编码问题。
. M: H) R: [7 K2 e cookie不安全8 { w. w1 _ Q
练习:: z8 a) @$ u. H' [; h( `8 M$ Q
写一个Add_FindCookieServlet,该servlet先查询
' T5 F4 @- F" V2 s# a' m) l 有没有一个名叫name的cookie,如果有,则显示5 d1 f+ `% m' @. ~9 X4 i
该cookie的值,如果没有,则创建该cookie(
1 w7 a2 c- f" t( M- T cookie的名字:name,cookie的值:zs)。
1 h5 B3 f! r% U+ w! p0 C
5 e6 \& `7 ?( N& l6 J2 _0 G4 | " m2 H# a- Y# N" l5 d' c
4)session V2 F6 L8 o3 S6 k- u k0 d; \0 w' ?
a,什么是session?
% F6 T+ q$ F, D$ g: \ 浏览器访问服务器时,服务器会创建一个session
5 v8 K; a4 b0 H, y# ?% J' K 对象(该对象有一个唯一的id, 一般称为sessionId)
4 \" u$ D; V: O' U2 Z 。服务器在缺省情况下,会将sessionId以cookie3 b) Z# | u, m% C2 ^- y) q
机制发送给浏览器。当浏览器再次访问服务器时,$ Y t, J3 Y$ `6 |
会将sessionId发送给服务器。服务器依据sessionId! {# A2 V g. I O0 `! x4 F
就可以找到对应的session对象。通过这种方式,
* ~+ {: E2 g( @' _% ~/ c+ \ 就可以管理用户的状态。% Z7 I, J# l. r
b,如何获得session对象 G& n" X: v/ {+ X
方式一:# }/ [0 _# v9 Y: [
HttpSession session =
3 j& x4 v# N$ U5 z$ Q request.getSession(boolean flag);
- _& J! n o, G1 ^' i6 ^ 当flag = true:
0 b+ n' s% n( q9 f 服务器会先查看请求中是否包含sessionId,6 `* O: [" C9 ^5 x7 H0 q( \
如果没有,则创建一个session对象。
7 R; k1 f& x5 L( i 如果有,则依据sessionId去查找对应的) X* i& j2 v7 K! g) S& g
session对象,如果找到,则返回。. K u; n6 C+ u+ E! e& g' I* `' c) V
如果找不到,则创建一个新的session对象。
+ j8 ]2 @/ |$ g, n$ }: g 当flag = false:+ j4 ]6 l% A( x. i8 m% X) ?
服务器会先查看请求中是否包含sessionId,
+ s5 Z# u3 Y3 }! l1 S f1 w+ }' i 如果没有,返回null。- W$ K/ `1 @8 a$ n8 R. F8 O
如果有,则依据sessionId去查找对应的4 l6 H# q' A Q8 H- n
session对象,如果找到,则返回。& P* u# G( K3 H% j1 K, X* G/ J
如果找不到,返回null。* k% q- t! e) e. A# t6 h* w* v
方式二:6 Y5 S7 |8 o. a
HttpSession session = 1 P; p+ W; O+ l* A& @, o
request.getSession();
8 ]7 x' g" [) w* n; \ 与request.getSession(true)等价。$ y2 J( ^4 Q4 y }! I
c,HttpSession接口提供的一些方法- t4 {! A' ?" Y4 q9 ?# V
//获得sessionId。2 t) k- e J- W7 G( B+ {
String session.getId();
7 [3 r1 k# u4 m2 \1 E8 n2 M0 ` //绑订数据+ g8 Z3 e: t& o' c* e
session.setAttribute(
! u% u, m O: f$ d7 I String name,Object obj);
. _0 U- a+ x* E$ H //obj最好实现Serializable接口(服务器
8 G0 n; P+ ?! b: | 在对session进行持久化操作时,比如钝化
/ M/ \6 N/ G L2 z( e 、激活,会使用序列化协议)。
" g+ W3 p5 p$ y# j! c/ ? Object session.getAttribute(String name);6 D* A3 a/ k' U% S( O
//如果name对应的值不存在,返回null。8 E0 q$ f4 K2 o: f1 e; b/ y
session.removeAttribute(String name);
3 N$ r# l7 N7 ^/ i7 S) C! M4 U d,session超时
- o) v d, N, r) b! p9 F 服务器会将超过指定时间的session对象
' M: `+ L7 b! a- F4 ~: B 删除(在指定的时间内,该session对象没有0 f, _* P( x' G& d- l
使用)。' @1 P7 n8 V& Y5 K, D5 @1 m
方式一:
Z. d% @$ p9 r3 H+ T% Y5 O7 `: ~ session.setMaxInactiveInterval(5 H: n, Y* n7 x4 K; v K& i9 V
int seconds);
^8 ?, t! G6 }! G7 E! R4 z4 C 方式二:' k; R. |( J" K* Z
服务器有一个缺省的超时限制,可以
! |" D4 g8 i1 w1 n 通过相应的配置文件来重新设置。8 n9 z! v2 ?; v- t4 w
比如可以修改tomcat的web.xml(
g+ O" P8 B" Y. L2 O tomcat_home/conf下面)。& _- d: Q! N" G9 M, Z7 L
<session-config>+ I0 f* ?0 p1 b9 ~/ F
<session-timeout>30</session-timeout>
, Z7 L. E, Q( v </session-config>$ w- U' l% {% p! _. b2 n9 |
另外,也可以只修改某个应用的web.xml。+ G/ K& X8 U' p3 C8 M
e,删除session
: r' f; _$ ?0 C1 N session.invalidate();9 {. x; n' ?; g* l1 R) t
( f# t4 T. z I3 J4 y1 R
案例:+ b+ R* e+ i8 _8 M" J
session验证
]4 G# d* `1 p) ^" L! V step1 在登录成功之后,在session上绑订一些数据。
$ {) a* m I0 I8 }1 w, `4 i 比如:
6 Z/ n h, L! N* x( P session.setAttribute("user",user);
; {+ F( N/ Y' f step2 在访问需要保护的页面或者资源时,执行
+ n" Y7 \* L& L' Z! b$ b2 _% C Object obj = session.getAttribute("user");. b' X5 ?0 D4 e8 W' l. H1 U
如果obj为null,说明没有登录,一般重定向到: q. a7 B) q H0 C+ ?: t/ p
登录页面。# n* @1 {5 z1 N) H3 V6 V
|
-
总评分: 帮币 + 5
查看全部评分
|