该用户从未签到
|
2、状态管理
, V/ j& ]. A6 y- P( p: u/ Z! q: l 1)什么是状态管理
6 }( b# O. k2 n( s 将客户端(一般是浏览器)与服务器之间的多次% y* r, d/ a4 f! R! F
交互当作一个整体来看待,即将多次操作所涉及的) R$ I$ [$ C8 ~
数据记录下来。
, p6 \4 t. b4 |2 \2 D& a 2)怎样进行状态管理7 }- M* ]/ s. _
第一种方式,在客户端管理用户的状态* y# w b9 _$ t6 o
(cookie)。' V( F" x# o$ Q# L" a+ H
第二种方式,在服务器端管理用户的状态
8 w6 s ~2 C8 n _ (session)。- Y" @0 Q% Y8 }' b: _
3)cookie
. U2 s0 [$ \' P& V5 n' P/ V a,什么是cookie?
2 A. q1 V" v% h8 b4 s5 h# Z 浏览器在访问服务器时,服务器将一些数据1 |% i3 S5 Z7 |+ _2 y ^& H& [ Q
以set-cookie消息头的形式发送给浏览器。浏览/ v3 s& X, a; {8 D6 h0 v. \0 O
器会将这些数据保存起来。当浏览器再次访问4 b! S% }# z: u8 x6 @8 m
服务器时,会将这些数据以cookie消息头的形式
5 \1 m( [0 L4 B1 r 发送给服务器。通过这种方式,可以管理用户的: o. v' Y+ i* m+ P
状态。
5 e& n( F, j+ S' e" n( Y b,怎样创建cookie?" _3 ~! K* x) J- k% [
Cookie cookie = new Cookie(String name,. B1 X. C: G2 g, A5 B8 [
String value);
3 g N7 X/ ]* E* w; @, J p9 B response.addCookie(cookie);
* q; `# g" W$ V* x' A& r c,查询cookie8 N2 U) J( C6 i
//如果没有cookie,则返回null。
# \2 q- k& L( g6 V Cookie[] cookies = request.getCookies();+ N( v1 @ B* p8 c4 {7 q# P8 ?
String name = cookie.getName();
& S( |9 c* r0 Q- U/ q5 p b" Z- x String value = cookie.getValue();6 e% K! W% a- C" [4 i- k6 x. }
d,cookie保存时的编码问题- R+ `/ E* a% I# a( T- v
cookie的值只能是ascii字符,如果是中文,
: O& Y5 b& n o' ^) Y 需要将中文转换成ascii字符形式。. B0 |4 p1 Z' z0 \1 ^* Z& x5 D
可以使用URLEncoder.encode()方法和* Q/ o$ L1 c# n6 g* i/ q7 r. o
URLDecoder.decode()方法来进行这种转换。
8 \8 S8 |* V7 H7 }8 c- e+ e e,cookie的保存时间
" y6 I1 k- b/ L4 _ cookie.setMaxAge(int seconds);( {7 d) B, g8 s$ L* X6 I$ O3 n
seconds > 0:浏览器会将cookie以文件的方式
- w( Z9 q" n9 M, i 保存在硬盘上。在超过指定的时间以后,会删除( y6 D, M( I2 \8 s$ {
该文件。% x# e7 P X* c" n8 F
seconds < 0:默认值,浏览器会将cookie保存
% I/ ]! o/ y: t0 y# m I' b& J 在内存里面。只有当浏览器关闭之后,才会删除。* M4 l! |5 e( j0 j" w
seconds = 0:删除。7 F7 w! G4 S9 `
f,删除cookie
8 _3 p9 ~6 M2 r# t; D 比如要删除一个name为"username"的cookie。& o3 U) [- \' `# w1 x) k; A
Cookie c = new Cookie("username","");
1 i( _7 K) B* e W0 v c.setMaxAge(0);* s) |' u" r- J* J/ \1 K4 r
response.addCookie(c);& `. `1 O I/ f9 F
g,cookie的路径问题
, [+ F! b1 m% J- L- j 浏览器在向服务器上的某个地址发送请求时,! ~5 S$ P, U v) E/ l
会先比较cookie的路径与向访问的路径(地址)是
' t$ T# ^7 I% h* N* \# Q& o- v6 f 否匹配。只有匹配的cookie,才会发送。* ^% Z! E' f! o3 t6 u% g
cookie的路径可以通过
8 B/ w/ {* p& f cookie.setPath(String path)方法来设置。
, L5 o4 f* c# [. u# r 如果没有设置,则有一个缺省的路径,缺省的
" {$ T8 A, N, @. z 路径是生成该cookie的组件的路径。+ H, h, g% c6 u
比如: /appname/addCookie保存了一个cookie,
# C4 n( r6 ]5 W% w, K! Y( X 则该cookie的路径就是/appname/addCookie。# P# c" y6 U `3 t
- Z) e% S# {- h$ I$ F" P; W
规则:
8 W. Y7 A7 ]1 Y cookie的路径必须是要访问的路径的上层目录
8 ]/ Q3 |% B( c s+ r8 R 或者是与要访问的路径相等,浏览器才会" n( m# f* y5 p
将cookie发送给服务器。
4 s7 k3 U; {/ ^( y% K$ e
3 Q$ }3 r0 }& R/ p, K 一般可以设置setPath("/appname"),表示访问
+ h4 ] F! W: u1 B" ^# U 该应用下的所有地址,均会发送cookie。
' L* u1 K# S3 \- D9 D h,cookie的限制
) d5 J# V5 K" O; [ cookie可以禁止: W; D* b3 [. @4 v" S
cookie的大小有限制(4k左右)1 N: i! q4 R" \
cookie的数量也有限制(浏览器大约能保存300个)
' X4 f: H1 D5 U5 ]0 e) @$ `$ H cookie的值只能是字符串,要考虑编码问题。 T% C6 {" u4 S- k2 m2 S* w
cookie不安全
$ F& k! d1 p& { 练习:* C* [6 P. G( e" G- H Y
写一个Add_FindCookieServlet,该servlet先查询
2 K8 c4 x6 H3 \8 g) O# g 有没有一个名叫name的cookie,如果有,则显示4 }6 V: ]" {1 c* v9 u- l! l- H
该cookie的值,如果没有,则创建该cookie(
# p3 d9 w: t7 E$ D. K7 Q cookie的名字:name,cookie的值:zs)。# T% d. _( x8 ~3 T8 }) ?
( f: b5 N" ?1 ~6 N) M$ ]$ R4 \
+ r1 b1 Y! I3 n' ]' \ 4)session & c" }- G- T% D
a,什么是session?; `. C8 w% W" P9 V% \# {! s& h' [
浏览器访问服务器时,服务器会创建一个session7 c# ?# n! `/ k8 P0 @
对象(该对象有一个唯一的id, 一般称为sessionId)
. _" v' H8 T5 w/ _+ ]8 V0 U9 p4 S 。服务器在缺省情况下,会将sessionId以cookie D0 {2 C& u6 t) Y( v( t* Z: f4 F
机制发送给浏览器。当浏览器再次访问服务器时,+ O" f; D$ }% R' l5 |
会将sessionId发送给服务器。服务器依据sessionId
1 w1 W0 u& f3 s9 T3 p6 P6 v% s 就可以找到对应的session对象。通过这种方式,
! ^' j: O) m0 c 就可以管理用户的状态。. L8 j# x# s1 Y4 s* {
b,如何获得session对象
0 N1 |, ?1 y' L1 p& j 方式一:- P- E- o( c* X: P! d
HttpSession session =
( D- l( K) l) ~: b6 I: b request.getSession(boolean flag);' ?' u; b8 [% C+ l# q* M; i
当flag = true:% Y2 w( u- |/ P7 k9 v9 @
服务器会先查看请求中是否包含sessionId,
* x) m" \7 g0 a0 g# \ 如果没有,则创建一个session对象。
( R5 t( F0 w6 A& H, `6 G# k 如果有,则依据sessionId去查找对应的
6 P% y! ?9 G2 D9 R# y/ W' i session对象,如果找到,则返回。
0 b( [9 x( s6 n. W( ?. b 如果找不到,则创建一个新的session对象。
: N% m9 i* `$ l7 I' Z- p' R/ y 当flag = false:
- x/ t( t6 |3 `, ]2 N5 W 服务器会先查看请求中是否包含sessionId,9 l& I- e& h9 c5 b
如果没有,返回null。: m: G* S6 p% ?- y: U& Y& R; ^
如果有,则依据sessionId去查找对应的
/ v4 Z/ O, l' H session对象,如果找到,则返回。
+ |5 d3 R, P. J9 D 如果找不到,返回null。
' \! I5 V! }7 t+ q 方式二:) k1 W, O: {6 h$ [
HttpSession session = % J z* ?( Z3 }& W
request.getSession();. ]2 V' V! m `. c. J# x
与request.getSession(true)等价。
( E/ [ u8 U) g c,HttpSession接口提供的一些方法
* ~3 f0 e i! F% m, i //获得sessionId。
4 C9 D8 }' y2 T) w String session.getId();
# y4 ]3 [( X* u* l //绑订数据0 W9 p) w1 T' Z
session.setAttribute(
8 N! N3 b1 o5 n String name,Object obj);
9 W( \; S8 z5 D& B& O( w* O //obj最好实现Serializable接口(服务器
! h5 T. Z( t* Q( d ` 在对session进行持久化操作时,比如钝化
% O/ p+ _+ F Z: g4 Q 、激活,会使用序列化协议)。$ V- e5 S O1 ] ^
Object session.getAttribute(String name);
- a, i+ X8 ^/ p, w7 U //如果name对应的值不存在,返回null。
- y; L1 H. E3 p% O t session.removeAttribute(String name);
# w O0 Z* J6 x2 Z( @* V& Z d,session超时
" A3 ?6 `! g4 E( y/ v. ` 服务器会将超过指定时间的session对象
- D1 ?% d5 s7 k. P 删除(在指定的时间内,该session对象没有% G& E- {& J! ?1 v. M2 Y
使用)。
k1 U/ V% t4 V: K4 b; I: \5 @ 方式一:) N% e/ {' n% g: H9 @ V$ r
session.setMaxInactiveInterval($ ?% B# `4 D. u4 c
int seconds);
/ y4 S7 v: l% k+ k. r2 r/ e/ R 方式二:
# E- \ F& F* ^# E* H 服务器有一个缺省的超时限制,可以' k6 W' Y7 I9 ~
通过相应的配置文件来重新设置。
! K! M) k) o5 L- I5 i( [& T 比如可以修改tomcat的web.xml(
% c7 j' ]+ _3 `2 S( I- y" W, U tomcat_home/conf下面)。. k$ t- m+ n" S; r0 v, K+ b
<session-config>) i5 P* ?# m1 H+ O3 {, `
<session-timeout>30</session-timeout>6 F% }' V; V1 ]
</session-config>
% S& e' l. s0 F M3 v" J/ \ 另外,也可以只修改某个应用的web.xml。
8 J$ p4 W) |7 C. A0 q e,删除session
7 \) g% A G5 ^3 {' M+ y session.invalidate();
, @% C6 j1 b0 A5 C6 `! u: K
! H$ ^5 q ~( T) a: P 案例:
$ q1 N" Z3 z. E3 H+ @# ?1 }! X) {3 d session验证
( M! I+ N- I* s- p/ ?- d) _ step1 在登录成功之后,在session上绑订一些数据。& L; X- B5 ~$ r( l4 i) y
比如: ?2 S/ F, R1 a2 M8 c% Z
session.setAttribute("user",user);
+ R+ O( q/ E5 t' }- I: Z) K step2 在访问需要保护的页面或者资源时,执行
3 i+ A/ s+ x/ n5 s6 m Object obj = session.getAttribute("user");6 I' Q# k A$ ?" G. b
如果obj为null,说明没有登录,一般重定向到
Q, x7 k6 \$ u& G, t5 ` 登录页面。1 B" h- s6 k; N7 @* F0 r
|
-
总评分: 帮币 + 5
查看全部评分
|