该用户从未签到
|
2、状态管理
& |8 U) w2 E* L; E2 X! G0 O1 g+ X+ V 1)什么是状态管理
9 ]+ s' H6 N+ u# \0 n6 c* k 将客户端(一般是浏览器)与服务器之间的多次- \ u' S2 t" d4 T1 m% Q
交互当作一个整体来看待,即将多次操作所涉及的9 I& b3 X2 ^2 B
数据记录下来。
o+ m2 y0 A7 I" M( f& ^ 2)怎样进行状态管理
/ j; W4 T* Y8 A* Z 第一种方式,在客户端管理用户的状态
* l" h# O" E+ J/ ^ (cookie)。
, y3 n- F% C. R 第二种方式,在服务器端管理用户的状态' S+ h' j. Q3 O! u4 n
(session)。: Q- h. n% ]+ j9 `) }) m R
3)cookie3 Y" ?' [- I% w9 _( G7 P
a,什么是cookie?. b6 Y8 r. [# P& y. g# \
浏览器在访问服务器时,服务器将一些数据4 h3 \7 S! A6 x x: Z
以set-cookie消息头的形式发送给浏览器。浏览+ N6 N5 H/ N" z" C
器会将这些数据保存起来。当浏览器再次访问
4 p- R* y' N- |# h. v. ]2 S 服务器时,会将这些数据以cookie消息头的形式; q/ ]3 p# j; H) f% f
发送给服务器。通过这种方式,可以管理用户的
0 _" Z6 V- L C4 s+ h 状态。
& s8 P. c6 S* ~1 [2 I9 Q1 P b,怎样创建cookie?
" n$ W" L/ M$ h Cookie cookie = new Cookie(String name,
. B: a" [& p/ A1 \# F String value);6 c4 D4 Y$ r1 H, R4 x. r
response.addCookie(cookie);8 p# L- c5 Y- N/ J8 B$ f1 p. ~$ I
c,查询cookie
. u( T+ P3 h4 }1 S- X/ ? //如果没有cookie,则返回null。8 o- ^$ a: B% W- B
Cookie[] cookies = request.getCookies();! d- ?9 N$ t* ~
String name = cookie.getName();. A. Z4 g! r( Z& F) D/ n o
String value = cookie.getValue();4 q8 w: E) t" c. j) ~$ E
d,cookie保存时的编码问题6 w/ [! F* K, e, P, N6 r1 [
cookie的值只能是ascii字符,如果是中文,) \% V7 c, z1 e+ ?. H& T9 a% A2 B
需要将中文转换成ascii字符形式。
, L* A7 D) H9 {6 n 可以使用URLEncoder.encode()方法和2 Z7 w6 b7 Z- p. p- K
URLDecoder.decode()方法来进行这种转换。
G' B: W$ T0 g) v0 J2 B e,cookie的保存时间) A0 F6 t& h# ~0 G
cookie.setMaxAge(int seconds);% }6 P0 x7 r5 N
seconds > 0:浏览器会将cookie以文件的方式7 S/ |! D2 J; m4 ]
保存在硬盘上。在超过指定的时间以后,会删除) w0 C: m$ p, n% e4 G9 x7 G4 p2 ~
该文件。
7 u4 N' T9 w! l seconds < 0:默认值,浏览器会将cookie保存
* ?% A: x! C$ F0 V& J" { X7 t 在内存里面。只有当浏览器关闭之后,才会删除。5 b$ L: q* V6 _: |9 v; x3 M- a, a
seconds = 0:删除。0 T3 z1 K2 e1 F& J8 K9 [% z: Z/ ? j
f,删除cookie& r4 ?* c- O! {/ q7 N
比如要删除一个name为"username"的cookie。: R6 i5 h0 h, t% e1 s+ W
Cookie c = new Cookie("username","");
2 S0 t2 _8 _9 K" i. ^, ^/ k. i c.setMaxAge(0);
R; }4 B' S2 @+ T f4 g9 A response.addCookie(c);
4 {! {5 P; A6 p0 T, Y& v2 I% O g,cookie的路径问题
7 O3 {; ?0 U0 k5 B& w% ]/ s8 B 浏览器在向服务器上的某个地址发送请求时,
" m' ^/ @8 i6 ]/ f4 ] 会先比较cookie的路径与向访问的路径(地址)是
4 a7 R1 i J( o/ Q& E+ o% U 否匹配。只有匹配的cookie,才会发送。2 E. K+ P) o; |6 }2 o
cookie的路径可以通过" Z K: F& |; g A) ^0 [
cookie.setPath(String path)方法来设置。/ q. V- S+ }. M/ g- s8 g
如果没有设置,则有一个缺省的路径,缺省的3 i( B# V0 [# X: p9 V
路径是生成该cookie的组件的路径。
, u3 x) @2 N2 \/ I, T5 R8 e! z1 B 比如: /appname/addCookie保存了一个cookie,
, V7 Y2 t8 ]8 y 则该cookie的路径就是/appname/addCookie。4 ?* y/ H7 G5 e: Z0 G: C) l
. @+ W& l$ W" V; G* s' q
规则:7 Z$ D. M3 ^5 ?, B: p! t
cookie的路径必须是要访问的路径的上层目录0 f0 J/ U( J# R
或者是与要访问的路径相等,浏览器才会
4 Z. Z" q2 T r! _9 O- l 将cookie发送给服务器。
; L S, y+ F/ b
C% m# I& a @2 r; Y2 p% {# Q8 I 一般可以设置setPath("/appname"),表示访问
* a! y$ G4 c0 J6 Z 该应用下的所有地址,均会发送cookie。
# h5 g" B- L0 H% v h,cookie的限制
/ k0 H3 O1 ]$ C w) D3 {: s8 t cookie可以禁止$ P7 G: W2 n; h( g4 O/ x/ R9 A! U
cookie的大小有限制(4k左右)
9 n% j6 S7 g+ Y8 V Y3 T cookie的数量也有限制(浏览器大约能保存300个)
3 t( m5 c Y7 ^$ h2 U cookie的值只能是字符串,要考虑编码问题。
5 _0 U/ l9 s5 h cookie不安全; ]# [3 Y( O9 s) j" x+ O
练习:
) s- h3 ^' E9 X) U; R9 N' P( X 写一个Add_FindCookieServlet,该servlet先查询
6 y0 M! N1 l! e5 g" q; y4 g 有没有一个名叫name的cookie,如果有,则显示
' _! f3 p) ~" I" A- z) d8 l% L 该cookie的值,如果没有,则创建该cookie(
4 }& `5 ]& B& { cookie的名字:name,cookie的值:zs)。0 ^/ g5 s2 `" s- W5 t
/ z+ i6 Q- f2 @& Y" w6 p# g
! U7 z% h* w+ O2 k O5 u 4)session 6 l/ {' @5 h. }+ Q; q8 ?+ C. {
a,什么是session?
) u- i! N7 z8 N 浏览器访问服务器时,服务器会创建一个session
' m$ u" N, `) J) z; A4 h 对象(该对象有一个唯一的id, 一般称为sessionId)
: f! W8 x- O/ J# T 。服务器在缺省情况下,会将sessionId以cookie: t3 K/ }$ c) ?9 |7 S' I
机制发送给浏览器。当浏览器再次访问服务器时,/ | i# A$ |' z) [- E
会将sessionId发送给服务器。服务器依据sessionId
2 j5 C ~' x, Q- ^ 就可以找到对应的session对象。通过这种方式, R2 n4 T2 u2 f' J0 u
就可以管理用户的状态。2 B* U* u2 ?* Y0 |
b,如何获得session对象9 m0 j: l& b; ^& I% Z
方式一:3 h0 D4 X4 ~2 S2 z6 ]9 l( b
HttpSession session =
5 C6 @1 m. x& Z' S- t request.getSession(boolean flag);
! G% e: \1 V7 o 当flag = true:# J$ k2 v3 C1 q! R% i
服务器会先查看请求中是否包含sessionId,. [8 M+ H4 r- O! I
如果没有,则创建一个session对象。
- Y! a( m7 ]! ^6 ^1 ` M4 R 如果有,则依据sessionId去查找对应的! [* X/ I M, R
session对象,如果找到,则返回。( t0 V1 c" w# z }+ d- z, w# x2 p
如果找不到,则创建一个新的session对象。
& S$ w: c0 p; g 当flag = false:
! Q! n& }. @# K) _$ s+ T! ^) d 服务器会先查看请求中是否包含sessionId,
, J. C( F) q3 J5 f. x% [- y- C/ n 如果没有,返回null。
1 A' M3 x8 B! @; ?; z 如果有,则依据sessionId去查找对应的
6 Z/ h+ g9 j3 e6 o% E session对象,如果找到,则返回。8 [( O3 Z U8 i- P
如果找不到,返回null。. q' C3 j7 T$ R. v
方式二:
. b2 Q# n; e! b$ ~$ q d" a HttpSession session = 1 v# g4 v0 _3 H: E" ~* M3 y
request.getSession();" O' A" f! c, u% f! X, ?" ^
与request.getSession(true)等价。 c- c; f; v" k" w( Q# t* L
c,HttpSession接口提供的一些方法& N2 c! R+ v- g4 q% s
//获得sessionId。
2 Q( S! z$ _# V+ R String session.getId();+ a/ C/ X# G: t8 D. H
//绑订数据
- i% O. f7 T0 j! O q+ Q4 K2 F session.setAttribute(1 z5 g* ]; J7 c
String name,Object obj);
9 B j, ?3 `& r* } //obj最好实现Serializable接口(服务器
4 X* D/ G$ n$ |( F' `+ c$ b 在对session进行持久化操作时,比如钝化
2 \0 y4 j! s" `( T/ A 、激活,会使用序列化协议)。% q; v# t2 R) |0 p, K4 O; l0 i
Object session.getAttribute(String name);
+ R, B! d# t5 H% Z9 `7 X( o //如果name对应的值不存在,返回null。( P X4 h6 p8 ^
session.removeAttribute(String name);
2 m0 R& Y0 ^! p; v1 M d,session超时
/ s* Y% K9 P: n* X( K 服务器会将超过指定时间的session对象 O/ \' w6 z' u0 N1 M4 P' w8 |
删除(在指定的时间内,该session对象没有
: y, T! S# T& A 使用)。9 U5 ~2 ]0 Y4 o9 V$ l0 X4 ?
方式一:
. Q+ {4 R4 X. u4 m% } session.setMaxInactiveInterval(2 ^; w# G3 _/ n: T# \; A& M0 d
int seconds);% W" a$ ~, ~7 u" [! ~2 F% _2 C
方式二:) X$ D, a# w; ^, k: A( |' p8 _
服务器有一个缺省的超时限制,可以
6 H& }6 |! c2 U 通过相应的配置文件来重新设置。
* F9 r6 F8 c0 S9 @9 D9 q* n# v" M6 D- h 比如可以修改tomcat的web.xml(( v* r" s; @+ O# l$ ?" c
tomcat_home/conf下面)。* W2 _# |+ o; |& j# }5 [% ~; C
<session-config>
8 v0 t6 q8 ]$ v% ^! L <session-timeout>30</session-timeout>- \. b5 W( F' f: ~9 `/ M5 M9 ~
</session-config>% k7 l9 T* U' B8 Q8 x; r
另外,也可以只修改某个应用的web.xml。4 v. S# ^5 c0 X3 M8 T
e,删除session
- U6 S" @( L `' Q2 Z7 P; ^/ |: _1 g session.invalidate();
7 c" l( ], \; p& N' d Q% t 6 E. w4 m% e' D D8 x! p
案例:1 |( d1 A; g; B) \ T
session验证
( ]& Z' ~0 X& v step1 在登录成功之后,在session上绑订一些数据。- F X6 b8 v/ c+ o7 J4 Q; l9 x
比如:
3 h7 j- d7 I) F. k. j* t* x session.setAttribute("user",user);2 m, \7 [! t+ p
step2 在访问需要保护的页面或者资源时,执行
7 R7 `' h, `, Z. T: J7 u( F0 Y Object obj = session.getAttribute("user");
. l5 _# C- U% {" x4 F& w 如果obj为null,说明没有登录,一般重定向到
% z2 F m; v7 C5 ? 登录页面。8 B, L1 z7 G& s: ?
|
-
总评分: 帮币 + 5
查看全部评分
|