该用户从未签到
|
2、状态管理+ H: e9 I% w* F4 F8 [. A/ N0 [
1)什么是状态管理
! {- I% w P8 e( j* I 将客户端(一般是浏览器)与服务器之间的多次
+ F" B; U& ~" n 交互当作一个整体来看待,即将多次操作所涉及的
2 z% c2 | I& L+ S7 h 数据记录下来。
# N+ i9 e" I' Y% |) ?) } 2)怎样进行状态管理
* D( T0 \4 j- L' M- b& h [- ?: t 第一种方式,在客户端管理用户的状态% e6 {) b$ c- d. b7 G5 ^
(cookie)。3 x z2 r- @' e1 d, J; Z/ q% |
第二种方式,在服务器端管理用户的状态
T0 r! C7 o4 D3 [ B3 G (session)。
- C' ~1 c8 l m 3)cookie
. r# ^4 u* e2 z2 s& D( j& t- W D a,什么是cookie?
: I% X- I& K4 d( o 浏览器在访问服务器时,服务器将一些数据
7 U7 I7 B: X3 F7 [$ o 以set-cookie消息头的形式发送给浏览器。浏览1 g- E$ p; a9 c: y9 e' ?
器会将这些数据保存起来。当浏览器再次访问
6 ^' H( A4 F/ d$ s& L 服务器时,会将这些数据以cookie消息头的形式
! m4 ?" `$ d& Z! Q 发送给服务器。通过这种方式,可以管理用户的 F& x+ g8 l: S$ l+ `* l
状态。
! q3 O& I" j' P8 M b,怎样创建cookie?
3 O8 _* ?' }( w" R% |* H1 f$ @ Cookie cookie = new Cookie(String name,% ^& B) m4 w. P+ u& P8 W# S
String value);
o+ m6 l% H9 S8 M; ] response.addCookie(cookie);
+ c2 m5 `: w' D# B( j0 M c,查询cookie
1 t/ l/ y4 K5 Z2 E: x) J //如果没有cookie,则返回null。% b" o) k4 q* a$ m3 W! U
Cookie[] cookies = request.getCookies();
7 E' ~) @6 r6 D0 d6 \ m$ E- H5 ^ String name = cookie.getName();% N0 E4 S8 q4 ?
String value = cookie.getValue();$ [+ V" j. y7 U, O/ e
d,cookie保存时的编码问题! j8 M) F# o6 n- |/ b
cookie的值只能是ascii字符,如果是中文,
' B" z9 ]. W, S$ r7 F# \4 U6 H 需要将中文转换成ascii字符形式。4 |! N: D6 h7 Z5 h+ h/ B. I) l
可以使用URLEncoder.encode()方法和8 z) c, S8 q# o: W, ^; ^2 [
URLDecoder.decode()方法来进行这种转换。# Y& r6 \8 Y8 L" d. a$ A
e,cookie的保存时间; A' a, o6 X7 D# @& t u; w
cookie.setMaxAge(int seconds);5 B3 a3 Z4 X L& z4 u# F
seconds > 0:浏览器会将cookie以文件的方式
5 ^9 r6 f! @6 T( |1 @% W6 z" _$ w 保存在硬盘上。在超过指定的时间以后,会删除- ?' L5 s0 l9 s2 B& [2 T& j$ F
该文件。
5 W( V: ]# v* U0 k7 P* q seconds < 0:默认值,浏览器会将cookie保存
: u/ M, r: I% X: b' F6 r8 e8 L9 | 在内存里面。只有当浏览器关闭之后,才会删除。
+ o' E# G" J9 ^& U: z2 E* E seconds = 0:删除。$ i! ^& g# [& b8 s2 K; q. B6 @
f,删除cookie9 X7 o6 R ?1 a& Y, N3 d: F
比如要删除一个name为"username"的cookie。8 m4 T ]" a; d# T& V
Cookie c = new Cookie("username","");
: L A" B9 f, S3 y1 |: w c.setMaxAge(0);
3 \. m. @. U9 ], `, B response.addCookie(c);; `/ Y5 e- R6 D9 \3 g
g,cookie的路径问题
- T# Y+ b2 I1 X, P; k0 ~9 H/ z4 O7 p 浏览器在向服务器上的某个地址发送请求时,1 ]8 e$ Y, _% e7 U0 t L8 _; \
会先比较cookie的路径与向访问的路径(地址)是/ T/ F) v0 |9 T6 X+ X
否匹配。只有匹配的cookie,才会发送。* B% U' I/ G$ I
cookie的路径可以通过
# w5 Q- f, F6 A cookie.setPath(String path)方法来设置。* H7 m- t l* L. d
如果没有设置,则有一个缺省的路径,缺省的* p$ V- ?! q! M( S& H' r3 S
路径是生成该cookie的组件的路径。
1 N+ y X' t! Q' l' N8 {* Z 比如: /appname/addCookie保存了一个cookie,
4 w5 v+ S+ r! ?& m/ J4 g2 u 则该cookie的路径就是/appname/addCookie。
0 n3 y& T9 z+ ]8 b* Q9 |4 H ?' w$ v% a, S
规则:/ u; e4 }7 E1 s* A( K$ e0 J
cookie的路径必须是要访问的路径的上层目录
# z4 c( t6 j' I" ?9 d' c, B4 `- m 或者是与要访问的路径相等,浏览器才会
) g2 t" j' I8 `' P0 N 将cookie发送给服务器。7 P' N: @2 W, W2 `! e6 d, }% D
& J7 f3 b3 L; b: u( K: g# ^3 [1 x
一般可以设置setPath("/appname"),表示访问
7 e6 o# J6 j* X. W# ^4 V 该应用下的所有地址,均会发送cookie。
}) N' U' Q( K0 l) k h,cookie的限制7 e( A9 X" L7 ]; X
cookie可以禁止
4 ]9 W& P- d% a. N cookie的大小有限制(4k左右)6 i' V% a) @7 P8 \5 W
cookie的数量也有限制(浏览器大约能保存300个)
2 A. n: P9 V# S b) P cookie的值只能是字符串,要考虑编码问题。
3 e5 t+ \9 ^% d- X4 [3 y3 H0 m# i- v cookie不安全
. g: S3 e6 d6 q, w! B0 E0 \5 k, V, Y 练习:
9 }5 u( w' z+ G 写一个Add_FindCookieServlet,该servlet先查询2 f1 C+ U( g0 P, h" `
有没有一个名叫name的cookie,如果有,则显示
$ F. O+ x, g7 R& k7 ]) T8 v- P 该cookie的值,如果没有,则创建该cookie(+ D! w- M; ]& O3 W6 D4 f1 ~
cookie的名字:name,cookie的值:zs)。+ e& f I( c& a7 K: v/ y, e
% u- v% t7 {$ D5 ^; ]8 s& j7 F
$ J5 y9 x& T) ?+ S2 ? [* w Y 4)session + R6 b) N2 V( y# Z' E4 }/ q" X
a,什么是session?9 |+ ]: @5 P' {& d6 }8 {
浏览器访问服务器时,服务器会创建一个session
6 q: H: E6 h0 ^7 D8 z9 G1 L7 F 对象(该对象有一个唯一的id, 一般称为sessionId)
- m' Q* s7 |; e( B, o 。服务器在缺省情况下,会将sessionId以cookie
2 I3 ~7 j/ V6 o$ n# ~5 n 机制发送给浏览器。当浏览器再次访问服务器时,+ O( O! x1 ?5 e" T7 Z
会将sessionId发送给服务器。服务器依据sessionId: H7 | A9 P% m% W9 j% M
就可以找到对应的session对象。通过这种方式,$ M4 n7 k; `3 Z( l4 ]
就可以管理用户的状态。
6 z% e5 }0 S) a7 x8 y. e b,如何获得session对象! A5 m9 G/ t! U( X5 e: q% f6 Q
方式一:
6 j P" j8 o6 p' L HttpSession session = % f% N( P/ T; `# S, e0 @
request.getSession(boolean flag);# A8 \ U, s: b4 ]. d9 m
当flag = true:
: J$ B; I5 J: [; z 服务器会先查看请求中是否包含sessionId,
; P! k, V! m1 n5 b% \ 如果没有,则创建一个session对象。# o3 ?6 m3 T! [. _
如果有,则依据sessionId去查找对应的
( s6 E# S6 F: Z }) P$ A session对象,如果找到,则返回。8 G O1 c/ @: `: K' G! ^
如果找不到,则创建一个新的session对象。
& J1 R8 h" F& U6 d 当flag = false:* x0 V! l- x7 v. ?
服务器会先查看请求中是否包含sessionId, z8 ~4 z2 p4 W
如果没有,返回null。) m" H8 r- e, J* K+ g* U5 V2 f5 ]4 T
如果有,则依据sessionId去查找对应的) N) X; j1 M2 J4 A& N% I) l
session对象,如果找到,则返回。8 O( ~& D( h8 k6 {$ f: y
如果找不到,返回null。
1 b; I: _3 ~; C% e' D 方式二:
) p+ T' P- w9 v3 N$ w( b HttpSession session =
6 @; I" U+ K" f0 c+ A. W: S- R request.getSession();
4 S1 H, H0 z' s! P* K9 L 与request.getSession(true)等价。
1 c2 j3 ~5 x, ^ c,HttpSession接口提供的一些方法8 I; Q/ U8 k9 A# S" H6 Z7 w" x
//获得sessionId。
9 K0 r+ b. U) R; [ String session.getId();
) ?) j' u3 |& l9 A, p+ | //绑订数据
4 T! S |1 z" x# p2 g9 q7 E session.setAttribute(
# Z4 {. a3 c# g2 D/ V5 c String name,Object obj);
5 G. A) y) K8 _ //obj最好实现Serializable接口(服务器
r$ k. ~/ E9 s5 K1 P& J, f 在对session进行持久化操作时,比如钝化- C5 }+ c+ ~: V
、激活,会使用序列化协议)。
4 `# }; Q1 `) v Object session.getAttribute(String name);
4 S. ?1 d7 V4 B* O1 ~3 E- t3 H1 f //如果name对应的值不存在,返回null。
2 T, V# h3 n/ E" y1 }; j0 r session.removeAttribute(String name);( ~: L% j" z l1 u, m5 t7 n2 {3 j1 i
d,session超时 T2 o) d( }& U) o: J" W$ l
服务器会将超过指定时间的session对象) H# {( _0 Y. ^
删除(在指定的时间内,该session对象没有6 f8 O7 Z0 |$ {* q+ J3 b f- W6 f) @
使用)。
& y2 h, X7 l" C 方式一:- h" x# g* O* p, B- X
session.setMaxInactiveInterval(
# i( r0 E' O% I- M2 C* H% i2 U: i int seconds);! y" `0 @$ D f. f/ }1 c
方式二:$ k3 C5 ~/ G1 i' ?7 x
服务器有一个缺省的超时限制,可以5 N3 z# K) c/ C1 m ~) S
通过相应的配置文件来重新设置。
4 r0 s8 T3 D2 w+ k X, V; {3 r 比如可以修改tomcat的web.xml(
$ c) Y# \! p8 F% {$ Y/ v, \: d. S- f tomcat_home/conf下面)。6 a+ f7 x9 S6 t' ^1 x3 U
<session-config>/ d5 e5 S% i) c2 }3 T
<session-timeout>30</session-timeout>
( I1 c6 i0 G, ]; V& |) e </session-config>
! L) E6 ?9 p, U. z1 C/ p& H9 Y 另外,也可以只修改某个应用的web.xml。3 m; H: q8 J! G+ l5 n* \
e,删除session4 g' E. e, g; {. m8 p7 p u) T
session.invalidate();/ ]/ j" w: B! s5 K5 ]. C
+ C6 m# ~3 y7 r& Z 案例:0 V/ G( N, E R3 U8 u
session验证- ^' Z0 d: w: `# X9 L, P
step1 在登录成功之后,在session上绑订一些数据。1 J k0 y" c0 q1 ~8 @
比如:
1 F: ]! c* N% q! f session.setAttribute("user",user);: c. K6 \8 A3 l
step2 在访问需要保护的页面或者资源时,执行
- L( j' C& g& P$ b9 W Object obj = session.getAttribute("user");. v: `2 G* H9 I7 m b) A
如果obj为null,说明没有登录,一般重定向到
) X( _. |) m. `& |3 }" | 登录页面。" b2 [2 F7 L" N+ C [$ Y
|
-
总评分: 帮币 + 5
查看全部评分
|