该用户从未签到
|
2、状态管理
F' O6 {7 Z: h0 T9 r) A& V 1)什么是状态管理
# O& D; g2 S. j3 E |4 x 将客户端(一般是浏览器)与服务器之间的多次
" g* \8 O" D! R6 F- M9 l5 U$ a0 R 交互当作一个整体来看待,即将多次操作所涉及的
- t6 p3 H+ K* s3 ]& } 数据记录下来。5 Z' c! o+ h% V" z; _5 ]+ Z: k! a
2)怎样进行状态管理3 c7 ?0 X) R8 h( }% t; D
第一种方式,在客户端管理用户的状态
[6 F# h- L6 ?; N" v& v1 A" L9 J (cookie)。. O9 m/ ` g! b4 c8 R
第二种方式,在服务器端管理用户的状态& b# o$ h7 w5 Q6 ^% {/ ~4 \
(session)。
3 k7 O; T% D. _4 B6 I" a+ Z3 T! H) C8 E1 P 3)cookie
- h$ G. _+ p! ] a,什么是cookie?
2 D; Q ?. ~# O# M 浏览器在访问服务器时,服务器将一些数据
7 H" x+ H' n8 q, E/ y2 ]) H5 B4 s% @& [ 以set-cookie消息头的形式发送给浏览器。浏览' j1 q5 M7 F: o9 w- U
器会将这些数据保存起来。当浏览器再次访问
W: g8 e+ H6 m S 服务器时,会将这些数据以cookie消息头的形式
! j: z- t4 L$ T. Z+ `) y0 T( [ 发送给服务器。通过这种方式,可以管理用户的: g% V* H, y) X
状态。6 D9 w0 g* P9 s4 ~3 |
b,怎样创建cookie?
- @" k3 q( n1 h# T Cookie cookie = new Cookie(String name,
# h2 I* q% _4 `* S! a l String value);* V$ ^1 s# V# r
response.addCookie(cookie);( d1 H% ~* y% S+ T f0 ~5 m7 c( T
c,查询cookie
' ~- Q/ f0 A# A- Q) E0 h //如果没有cookie,则返回null。
" e: J$ J, F# p% j1 j Cookie[] cookies = request.getCookies();) M6 T. t& k- K9 [8 ?: V4 ?" \8 h; O
String name = cookie.getName();, w' f5 P4 n' K0 Q# y# [
String value = cookie.getValue();8 x) L0 C3 W+ V: C7 s8 X) h6 k8 a
d,cookie保存时的编码问题3 m4 `: Y4 y& z' U# f" [3 @
cookie的值只能是ascii字符,如果是中文,
: T# H h. t9 G 需要将中文转换成ascii字符形式。
6 g8 O, G6 @) ]: ]. {% w8 m: x 可以使用URLEncoder.encode()方法和
: }$ P+ d* y) f- N URLDecoder.decode()方法来进行这种转换。' I+ u! d4 Z0 H0 i c: Q2 _
e,cookie的保存时间6 u" b1 q+ V1 F O7 _; V+ D
cookie.setMaxAge(int seconds);) Q) Q4 Z2 s/ [' f% E- X1 {8 N. q
seconds > 0:浏览器会将cookie以文件的方式/ k- k4 @ F! w7 h, C$ u M( P9 j
保存在硬盘上。在超过指定的时间以后,会删除
: F7 ?6 V+ E# h$ m9 s 该文件。1 W+ o9 n! m7 h5 }* C
seconds < 0:默认值,浏览器会将cookie保存8 D3 q" @) g4 a( c0 p7 R: P
在内存里面。只有当浏览器关闭之后,才会删除。" G" t- ^0 d! x& _7 z/ I ? S* c
seconds = 0:删除。
( A. _. i* ]- H2 l0 L' s* I f,删除cookie! ?, m+ `% {% i% q8 |
比如要删除一个name为"username"的cookie。
! T5 X# T* F7 b Cookie c = new Cookie("username","");, G- t: R% a! U& I. d& K5 q
c.setMaxAge(0);
; M2 C5 }2 }; M: @ response.addCookie(c);/ m1 y* V1 v% M( ~, m5 _4 P" V
g,cookie的路径问题
0 F# x* `4 k& I# P0 |7 a+ N 浏览器在向服务器上的某个地址发送请求时,! O3 M1 k8 l7 J: {% c; C
会先比较cookie的路径与向访问的路径(地址)是" R7 C6 I1 U1 P; m/ _$ b' a
否匹配。只有匹配的cookie,才会发送。# v8 z; Z8 U( x$ C0 H4 @1 o* l. e
cookie的路径可以通过
' y4 y2 P3 t9 ^* O- O- N$ e cookie.setPath(String path)方法来设置。' C! a! M E9 W+ }) r3 b! x
如果没有设置,则有一个缺省的路径,缺省的
( i' ?: X9 e4 e( [3 Z 路径是生成该cookie的组件的路径。9 z2 K2 |* a. [1 I! A
比如: /appname/addCookie保存了一个cookie,8 C3 Z$ w& N/ h5 C8 i
则该cookie的路径就是/appname/addCookie。+ j) |# M, s0 C1 T' |. p
. W8 }* y4 T. o* ? 规则:" K9 V! I8 X4 ?( f9 \' J
cookie的路径必须是要访问的路径的上层目录
+ Z$ V+ V, c9 G 或者是与要访问的路径相等,浏览器才会
/ y; m0 F4 }# J# P6 \ 将cookie发送给服务器。
a" Z- P; J% C- G: M " ^9 M$ r/ n/ H! \" O
一般可以设置setPath("/appname"),表示访问
( P) M% R& k# O2 y& a! U, ^ 该应用下的所有地址,均会发送cookie。
& T' q: U$ e/ [) d' s* ? h,cookie的限制
' d+ U4 {# @* Z& Y" M# W0 A" y/ h9 n% | cookie可以禁止
( j' G. h% Y1 b: c cookie的大小有限制(4k左右), J1 \( T$ d3 G% H
cookie的数量也有限制(浏览器大约能保存300个)
, a# t/ r" _( {& i( ^( k cookie的值只能是字符串,要考虑编码问题。
6 r( J0 g* g9 A" D# p( ~2 J cookie不安全$ ?" ~0 j. w" H1 R& m7 w+ o
练习:
5 V9 k) b/ Q$ n- g3 a3 o 写一个Add_FindCookieServlet,该servlet先查询1 ?& H. m$ [" u
有没有一个名叫name的cookie,如果有,则显示
, u$ v3 N4 T5 N) L5 E6 h7 d 该cookie的值,如果没有,则创建该cookie(
- I3 R" L( U3 v8 z( X# }0 u! T cookie的名字:name,cookie的值:zs)。
6 `. m& m# T" t: \, E( h4 ~
1 s& {. q& ^( L# c. c' _0 x
: U: ? e% b) y u* y8 v 4)session
8 l, N3 R' Z/ ^% }$ T8 | a,什么是session?+ e. D+ K1 z5 u
浏览器访问服务器时,服务器会创建一个session
( Q8 q. o% B7 o. ]# ^( E 对象(该对象有一个唯一的id, 一般称为sessionId)" ]2 I" z) v4 V, a
。服务器在缺省情况下,会将sessionId以cookie
/ q5 @, u! z9 N4 c' n% W 机制发送给浏览器。当浏览器再次访问服务器时,
. ~2 `' ^, ~: ]: J1 W; @ 会将sessionId发送给服务器。服务器依据sessionId4 w# S7 ~4 P+ |9 U+ x
就可以找到对应的session对象。通过这种方式, M8 H3 J# o7 B- I# l/ E& k3 A( `
就可以管理用户的状态。
+ g. {1 H( f, M b,如何获得session对象
- F$ g0 x) |7 U1 M5 l 方式一:! ?- H+ |' V5 N
HttpSession session =
* r2 A5 c) \3 @7 L8 U4 | request.getSession(boolean flag);
0 {4 U# Q7 {8 u* D3 ~ 当flag = true:5 n6 l' |+ F; T) L/ o
服务器会先查看请求中是否包含sessionId,
0 v [( I+ a' R9 X& _; W 如果没有,则创建一个session对象。
+ B7 E3 A: K0 y( w P 如果有,则依据sessionId去查找对应的+ v I( }- u( h+ r2 U/ G$ i
session对象,如果找到,则返回。
$ }) \: [2 ]9 ]- @. {, W5 {- g 如果找不到,则创建一个新的session对象。; T9 Z0 `* }" a2 b* ^" W
当flag = false:0 t7 `6 \9 K" _
服务器会先查看请求中是否包含sessionId,1 F$ q: {! N& e
如果没有,返回null。
a5 B5 a! J4 l) z 如果有,则依据sessionId去查找对应的
- B* z/ t2 V" V r6 r9 j session对象,如果找到,则返回。: G: X1 u6 I# n# k8 j4 |
如果找不到,返回null。5 N A0 `+ p* G9 R/ H# i
方式二:; I- u& ~* s5 C7 _+ G; C
HttpSession session =
8 I" [, M, {2 Y7 T5 m+ B& W% l, _- m request.getSession();
$ z7 W2 T6 Q+ y/ I" A 与request.getSession(true)等价。: @3 [6 \6 x$ q! a
c,HttpSession接口提供的一些方法' N- w" ?# ]/ U N: r2 ]% }
//获得sessionId。. J( K% @$ r }2 H$ I y
String session.getId();
" t9 [4 J W9 t$ w: x! V //绑订数据5 N' e5 S5 I! \$ S& [* d7 Z
session.setAttribute(
\; n2 G$ I/ [ String name,Object obj);
3 J. b1 t ^( q" S' s& X //obj最好实现Serializable接口(服务器
" x& _$ A5 h' b1 S/ P! X4 B 在对session进行持久化操作时,比如钝化2 }4 X! t& W2 g
、激活,会使用序列化协议)。
# j {; i" X2 G9 @& }% S4 Y Object session.getAttribute(String name);
L. ^1 v% }5 w0 y' t5 Q( _' \ //如果name对应的值不存在,返回null。
! K9 [1 _% j6 N) M# u( h6 a session.removeAttribute(String name);
, p% `. V) M: _3 u& J. c; m( s! m d,session超时, C* N+ z1 D: C8 }4 Q' y1 G$ d
服务器会将超过指定时间的session对象1 l/ {: ~- g8 Z
删除(在指定的时间内,该session对象没有& n0 Z: T$ M" u+ S
使用)。3 y! v! j7 D% w. I
方式一: `; A8 x4 e% D3 H% ]
session.setMaxInactiveInterval(! ~1 N- b# Z, \
int seconds);
+ i. x6 ?5 F0 L' O 方式二:5 }! O9 ?8 M# _$ w1 ?3 X+ }) E
服务器有一个缺省的超时限制,可以
, B( J' r( q4 \ 通过相应的配置文件来重新设置。
( ^3 ^4 K. y6 I9 Y- K 比如可以修改tomcat的web.xml(8 d( s# e, j) f' v- X
tomcat_home/conf下面)。
. K1 y, x: f1 k- ]1 D8 M <session-config>7 }' s) e* U K/ r: `4 h$ ^7 t
<session-timeout>30</session-timeout>, x$ W9 ^5 m, K" p" n
</session-config>
4 K7 E8 _7 C+ C# T- e 另外,也可以只修改某个应用的web.xml。" u- y7 P* C( H" l) ~) F+ Q
e,删除session
) O P5 d- z6 v# J session.invalidate();2 K9 T B* \+ ]. d9 W# d" g; Q* x
9 K- K; O" z0 X4 z3 Y6 `& q8 z 案例:. b H5 n m6 \0 B- A# r5 Q
session验证
3 a! s& C' r/ y, N: F# v step1 在登录成功之后,在session上绑订一些数据。5 s1 o' E1 O# R0 Y! }+ S
比如:
3 @! q5 K. w8 a: _; A6 B session.setAttribute("user",user); l) @5 p! {) D+ l% M) |8 R
step2 在访问需要保护的页面或者资源时,执行
( B* B9 X2 n+ M8 _# I Object obj = session.getAttribute("user");& n5 R; ?% y' w9 S1 D, d
如果obj为null,说明没有登录,一般重定向到
! c" D/ y( ]' a; z! _5 B 登录页面。( D) u m- Q6 @, b
|
-
总评分: 帮币 + 5
查看全部评分
|