该用户从未签到
|
2、状态管理& b! J9 N+ p3 g' I4 f6 e
1)什么是状态管理
% L o5 @2 ^. ]! r 将客户端(一般是浏览器)与服务器之间的多次% R" p, h$ m, T' M: _( y- p% a+ s
交互当作一个整体来看待,即将多次操作所涉及的
/ n) v) m( \: c2 ^8 B8 H, \3 o& z* o 数据记录下来。
' b' D/ T& ^% P' C+ U 2)怎样进行状态管理7 @9 [# v9 y9 k/ k
第一种方式,在客户端管理用户的状态7 }- B7 F( h( d# |/ Y, ^' g$ f6 z
(cookie)。3 T6 y0 s( c2 Z) ~" `' M8 G
第二种方式,在服务器端管理用户的状态
$ K: ^ \& O+ ]0 c (session)。! H- R/ }8 g+ ^
3)cookie
- J" y, v: {( g a,什么是cookie? }& G3 P$ j# j2 @/ Q# k6 `% L8 O
浏览器在访问服务器时,服务器将一些数据
5 L# N: c. H \4 j0 Q+ Y9 ~$ s 以set-cookie消息头的形式发送给浏览器。浏览' L6 h1 _4 B& @8 {3 k; i" X+ b. m
器会将这些数据保存起来。当浏览器再次访问
& ?6 R- _( e0 n% } 服务器时,会将这些数据以cookie消息头的形式' o- U# |9 W, [5 h7 v! E7 X
发送给服务器。通过这种方式,可以管理用户的
$ T1 y1 j9 L7 [/ f# H' C/ Q, g+ z 状态。6 ?/ }" ~( [( u6 m+ C t, l
b,怎样创建cookie?
: z: `* F# R/ _. ^2 U9 M0 g Cookie cookie = new Cookie(String name," K2 i. t# d8 Z- h6 n$ {# q
String value);
2 W# b8 X. E9 Z7 E" r' w( U. a) d response.addCookie(cookie);& G- g/ x. |# N! q4 s H* v- \
c,查询cookie
, b& s C: c3 m- d9 e+ M //如果没有cookie,则返回null。
l; d( `9 z& ~ Cookie[] cookies = request.getCookies();# O9 v; B) |! v! E) J
String name = cookie.getName();
% V* g5 m4 g: t" h1 J String value = cookie.getValue();/ y2 i7 Q: u/ O3 _" H) z
d,cookie保存时的编码问题1 V& K- O$ S7 B% c7 @. W
cookie的值只能是ascii字符,如果是中文,4 K% w: H* F: e# g; H
需要将中文转换成ascii字符形式。/ M( E2 F* h& N1 N7 C' ~$ a+ [
可以使用URLEncoder.encode()方法和
$ C( }5 q$ T! Y$ r9 L1 {: c/ K8 r8 o URLDecoder.decode()方法来进行这种转换。0 N+ q! `9 T& H ~4 @2 _
e,cookie的保存时间. k0 M: [& y- D. @6 D
cookie.setMaxAge(int seconds);" D, P! e& z" U
seconds > 0:浏览器会将cookie以文件的方式: F5 f1 o( W" \
保存在硬盘上。在超过指定的时间以后,会删除4 r' n% \9 R! {: p& v1 g9 C
该文件。
& W1 Q$ S2 ?* d" }* ^! I. I2 z seconds < 0:默认值,浏览器会将cookie保存
3 r' M: W& y1 I0 x) @ 在内存里面。只有当浏览器关闭之后,才会删除。( ^( {, ~5 m# V5 W5 W- m6 n- U
seconds = 0:删除。
& P. M z6 u" h) F% ]& `: u* k f,删除cookie
" e- d* b3 ^- F) _5 e' @: b 比如要删除一个name为"username"的cookie。3 \; Z+ L6 y" A3 r0 m0 j/ B5 s7 ~
Cookie c = new Cookie("username","");
t" B, ?2 e/ h( A4 E9 a3 C c.setMaxAge(0);3 g8 K$ v2 o0 y. v# {. n
response.addCookie(c);
/ K! H8 k( a& J' R6 O; T g,cookie的路径问题 V: \8 |8 A" H- B& A
浏览器在向服务器上的某个地址发送请求时,
1 D2 L% R* p3 [ S( M, r 会先比较cookie的路径与向访问的路径(地址)是
: t' [+ V/ n: ^( P b& o 否匹配。只有匹配的cookie,才会发送。4 G* d' |5 `8 G7 P
cookie的路径可以通过% V5 I; v4 r) _7 v: P: S% b
cookie.setPath(String path)方法来设置。
: U1 d U0 k0 ]$ I( O+ c 如果没有设置,则有一个缺省的路径,缺省的 H; ^# r D- X: L5 P' V+ q' }
路径是生成该cookie的组件的路径。% O% p1 b' F, k' M% ~ S
比如: /appname/addCookie保存了一个cookie,$ j! u: _2 }, ?8 u% l, o# N8 H
则该cookie的路径就是/appname/addCookie。" s. J- [/ o. u# S5 W; k+ g3 ?
* b& Q4 _5 N6 _! b# u1 ] 规则:: |4 D4 H1 t7 |3 }9 t: S2 [! W6 \
cookie的路径必须是要访问的路径的上层目录
/ T i4 b" b& K% g' b# ]7 d$ k6 t 或者是与要访问的路径相等,浏览器才会
7 ~# x. D) e/ }* E2 W6 r 将cookie发送给服务器。. b1 b; _; R; L; p( ^6 ]5 @/ h
5 V* S5 P+ y3 @% H" K; `+ Z
一般可以设置setPath("/appname"),表示访问
* n% \+ q: D1 I2 e( X7 n 该应用下的所有地址,均会发送cookie。9 \3 B% c' ]% N: c' O
h,cookie的限制
' z2 W; h* ^' G3 m& v! W; K# x cookie可以禁止+ `' {5 k5 d4 g( M' G% a$ p3 j+ S
cookie的大小有限制(4k左右)
* S- x0 L" `/ X1 g8 m; ~2 M cookie的数量也有限制(浏览器大约能保存300个)
% b# }# j+ U0 ~( B2 S" Q* P" L- V Q cookie的值只能是字符串,要考虑编码问题。! K+ t4 u% Y; A# T& j( p
cookie不安全
- Q7 Q( [9 z/ c5 D/ t 练习:; y4 K1 K5 h, ^8 r# b! S- e! J
写一个Add_FindCookieServlet,该servlet先查询6 C6 h" P/ q& s; P$ y) _% P
有没有一个名叫name的cookie,如果有,则显示
# g3 F7 g2 E# E T# t' W' T' s, X8 H9 \ 该cookie的值,如果没有,则创建该cookie(0 N" k2 L6 y; {& L) A
cookie的名字:name,cookie的值:zs)。( o: k: l) {5 S5 d5 B6 M' R
' b# F$ s! G1 P9 C 1 A/ {( i6 ~0 G' K q3 H
4)session
2 y3 z" _. ^$ J _; U0 @* v a,什么是session?. S& }7 m9 V% @7 Z
浏览器访问服务器时,服务器会创建一个session
' ^9 m+ D |, p7 x( F) c+ J 对象(该对象有一个唯一的id, 一般称为sessionId)1 F0 {) A% C V+ m- q9 H4 e0 B
。服务器在缺省情况下,会将sessionId以cookie
1 V ^0 h, n. e0 M0 o% R 机制发送给浏览器。当浏览器再次访问服务器时,! U0 H- @) w% ^- C0 u
会将sessionId发送给服务器。服务器依据sessionId
8 @/ y/ L, J% C/ H# S 就可以找到对应的session对象。通过这种方式,7 T' l9 \% G, |0 z7 Y( x7 Z
就可以管理用户的状态。( e, v" [2 m& k& J' b
b,如何获得session对象
( L0 u+ o, }3 V+ J 方式一:- l! p' [# z% p( ]1 R( e- S
HttpSession session =
* f8 ~- S; c+ S- W8 J request.getSession(boolean flag);
6 q& T1 z6 A) V 当flag = true:0 w; r% z% i0 W `* u& a
服务器会先查看请求中是否包含sessionId,
" ^' M) K% T0 j 如果没有,则创建一个session对象。6 _0 E. g( d2 B
如果有,则依据sessionId去查找对应的
; }# l5 B* F! S+ c* D; S session对象,如果找到,则返回。& s9 n1 S" |" u8 W- \: y
如果找不到,则创建一个新的session对象。
: i' G6 y4 x& D3 l# s 当flag = false:4 J* e. B8 y) H; y4 F9 t
服务器会先查看请求中是否包含sessionId,9 A) `( }6 F" j9 T$ S6 m8 f
如果没有,返回null。. q/ d/ ^ Y9 f( f6 _
如果有,则依据sessionId去查找对应的
1 t+ f1 Y7 U" ^6 ?, R4 c5 Y: D session对象,如果找到,则返回。( C1 {0 P# \9 k1 y9 d* m; E" ?
如果找不到,返回null。4 Q6 \3 |2 h& G5 J2 Z
方式二:9 `, @ [: E" g& r8 B8 u
HttpSession session = $ O2 O8 h" S, \4 z: C
request.getSession();4 g7 P6 L6 M) ^ f
与request.getSession(true)等价。/ J. f1 T6 t* q/ i3 G% ~ \* f
c,HttpSession接口提供的一些方法
2 O$ {& F! ?& ~' l. E4 P //获得sessionId。
- T9 `1 a& g7 [' J String session.getId();3 ?! c+ O& w) R3 d9 }9 t
//绑订数据
+ c I1 l4 {$ f. H session.setAttribute(/ U ~* V! V* N# p a, X
String name,Object obj);
1 W6 X c* }( m5 o //obj最好实现Serializable接口(服务器
* U2 n. c6 Y1 Y# N+ o 在对session进行持久化操作时,比如钝化
' p- v: T9 R, A$ P 、激活,会使用序列化协议)。
3 w: O7 A5 n C) c I8 s Object session.getAttribute(String name);
( f6 X" y; x& X& N+ X S& A, Y; U. ] //如果name对应的值不存在,返回null。% D; c6 m4 w. e* {' ~: ~
session.removeAttribute(String name);) Y; d9 @/ |1 d1 `' c% z- X( S
d,session超时
1 V, |; z4 R& h4 Z# |: ~. f5 w* R 服务器会将超过指定时间的session对象
2 m8 v" L0 \' u1 ^3 y7 X+ W- A 删除(在指定的时间内,该session对象没有
2 i! @9 y' ]+ I. @3 w a 使用)。 d6 ]: B4 e7 c& `5 `2 z: `) L
方式一:4 B1 B- d0 I# ^1 M/ N! K/ z
session.setMaxInactiveInterval(
6 ~7 e, k4 m7 D# i int seconds);
1 s1 S" n* w4 `* ` 方式二:# j" \: d: C; V( i9 [/ n3 d2 d
服务器有一个缺省的超时限制,可以
2 t! ]* ]* o* v# e 通过相应的配置文件来重新设置。$ o3 I2 m5 |1 q" F1 l
比如可以修改tomcat的web.xml(
7 N+ c) |; m4 q* G/ S tomcat_home/conf下面)。) r! _' @& e8 J1 V
<session-config>* A. T+ h" K$ P; j8 d' C
<session-timeout>30</session-timeout>, A1 Z/ z* Q1 w5 @ C* O
</session-config>
~. M" `8 J+ V( n8 _ 另外,也可以只修改某个应用的web.xml。
% W P) C, j! K1 B- V$ G e,删除session# X& P5 K. D6 o7 [- l6 @9 a m
session.invalidate();6 e! s& l4 c( H
5 K5 J0 i) e! { 案例:
9 ~4 M3 K, W2 v' I# u session验证
9 l( A' l) j+ W, ^0 Q step1 在登录成功之后,在session上绑订一些数据。+ f- w2 J0 S/ `: h0 t0 w' U" |! o
比如:
% K* g4 u o2 A' \) O/ l session.setAttribute("user",user);+ | O6 K" @, L/ h. T" m! T& D# O
step2 在访问需要保护的页面或者资源时,执行3 u) @3 z3 f* G$ h
Object obj = session.getAttribute("user");7 |: r( _+ W2 M/ ~% V- N0 j
如果obj为null,说明没有登录,一般重定向到
9 _' |& t. \8 Q. F1 D 登录页面。7 ~+ L! l& N8 X: T) H
|
-
总评分: 帮币 + 5
查看全部评分
|