|
该用户从未签到
|
2、状态管理/ r. f* ?; e1 s0 P3 C
1)什么是状态管理
. T7 H) O# [6 R( X8 O T& U$ v 将客户端(一般是浏览器)与服务器之间的多次
8 `. V% p3 k- m 交互当作一个整体来看待,即将多次操作所涉及的
. w; ~8 I/ j% D/ o7 g 数据记录下来。
7 x: k3 a( b( w5 c: X3 K1 Z; D/ h. b 2)怎样进行状态管理
2 V) }1 m3 o1 c2 l0 a 第一种方式,在客户端管理用户的状态9 q* S1 w# c* r1 r6 }6 K
(cookie)。! R2 f* ~" b+ `- ?# s5 c' I- \
第二种方式,在服务器端管理用户的状态
2 L, G5 q! Q, p (session)。
9 x9 e5 _* {: Q 3)cookie
/ t0 ~2 |+ x- z: Y3 @- m a,什么是cookie?( `' ^4 Z, \. H5 K M" f& Q! a
浏览器在访问服务器时,服务器将一些数据
, [8 X6 w7 A" U1 T8 K' v3 M e 以set-cookie消息头的形式发送给浏览器。浏览
- s0 E5 |4 B( l' h% R. g7 b0 Y 器会将这些数据保存起来。当浏览器再次访问* E$ X. }( R/ ^1 ~" l& B
服务器时,会将这些数据以cookie消息头的形式# }& h, T' c8 ^; V, a' U
发送给服务器。通过这种方式,可以管理用户的
; V% g( h7 e3 C! q; U 状态。. k% R L" P9 i0 [6 `
b,怎样创建cookie?
- ]% z+ w* E! e7 n6 e Cookie cookie = new Cookie(String name,, H/ X. P' R1 u) {& R, G
String value);+ N" w3 f0 n7 f
response.addCookie(cookie);
' M6 B/ {+ r1 [0 | c,查询cookie' s1 ], t# z( z5 N
//如果没有cookie,则返回null。! g, H/ T8 I4 v# Z
Cookie[] cookies = request.getCookies();
# V1 a$ t9 |- x( h% ^+ F String name = cookie.getName();
' V2 b% `4 c) o) v4 m4 X String value = cookie.getValue();
]' x6 R0 H& y7 ]/ ] d,cookie保存时的编码问题2 Y+ N' @, L% b& N1 g! z% y
cookie的值只能是ascii字符,如果是中文,9 H. G/ [5 X2 A) L; U
需要将中文转换成ascii字符形式。
+ y$ f- L+ s3 n# g 可以使用URLEncoder.encode()方法和
% F( W: g B) } URLDecoder.decode()方法来进行这种转换。* r8 r" e! x" v
e,cookie的保存时间 b+ \. F+ Z7 I% N* Y
cookie.setMaxAge(int seconds);
2 x% e& R, X" h* O4 M seconds > 0:浏览器会将cookie以文件的方式
$ `+ r9 r; c6 J- R- U6 T, Z 保存在硬盘上。在超过指定的时间以后,会删除
* E0 B% T6 ~! \% `! v, v 该文件。# M5 a) T" |# Z' l6 K3 {
seconds < 0:默认值,浏览器会将cookie保存0 ~7 Y" K8 T) |) X) I' z4 |
在内存里面。只有当浏览器关闭之后,才会删除。8 ?- ~: E, b6 r8 F
seconds = 0:删除。; v* [. ~# l/ r7 C
f,删除cookie
9 I% D! ?8 C5 X6 h$ g 比如要删除一个name为"username"的cookie。
& w# H( K% a3 _ Q/ Y Cookie c = new Cookie("username","");
" _# W" C v, H5 w c.setMaxAge(0);1 |, O2 J4 S: [& m
response.addCookie(c);
9 y. Y1 u! r( Q g,cookie的路径问题" J2 w, r* [- s4 I) a! S8 U
浏览器在向服务器上的某个地址发送请求时,( @3 { X0 L+ A
会先比较cookie的路径与向访问的路径(地址)是
9 Y% a+ U4 J9 y 否匹配。只有匹配的cookie,才会发送。
6 A. Z% P9 \4 J, s2 u cookie的路径可以通过
M e1 A4 ^4 v* B1 F4 X" | cookie.setPath(String path)方法来设置。2 s2 D7 h6 C' W' V+ v' }) O
如果没有设置,则有一个缺省的路径,缺省的
1 z2 U' u7 D5 ]" e 路径是生成该cookie的组件的路径。
# j9 ~& P6 r! t" f3 Q, P$ v3 { 比如: /appname/addCookie保存了一个cookie,5 M+ e$ [" A' G- N4 E5 k/ [
则该cookie的路径就是/appname/addCookie。
4 Y# h1 n W& u) S. e
4 `8 Q# c# w& J" w' M/ d2 c, _ 规则:' N5 `9 C) W$ p5 v: |# \6 n
cookie的路径必须是要访问的路径的上层目录* T6 U2 L( n& q" v) Z6 ~
或者是与要访问的路径相等,浏览器才会
- L" ~% G: R' ?1 n, g% X 将cookie发送给服务器。
& g/ B: h; P+ `1 f, ~ . `% w! A' }: @
一般可以设置setPath("/appname"),表示访问% ]# I( W, h j5 H5 v, I5 k9 M0 X
该应用下的所有地址,均会发送cookie。
0 d& u$ m# t; F# A8 N h,cookie的限制& W& O% v" ?; g
cookie可以禁止
s7 ?3 Y1 w# D+ y5 d3 N" N% S cookie的大小有限制(4k左右)
8 @& E/ G: C9 d cookie的数量也有限制(浏览器大约能保存300个)
6 \$ i0 S } H$ K& q/ G$ M/ P cookie的值只能是字符串,要考虑编码问题。
! N" U- V ^3 Y2 K Y: k- J$ u cookie不安全
: _4 q$ P2 c4 d3 Q 练习:
) P8 N1 S& |3 q. { 写一个Add_FindCookieServlet,该servlet先查询+ C- H& ~9 w+ |
有没有一个名叫name的cookie,如果有,则显示
3 b1 E/ {- q9 P; q0 l) ^) p 该cookie的值,如果没有,则创建该cookie(% }# p! Q" i; i, u) Y* ^2 i& j
cookie的名字:name,cookie的值:zs)。
" E: `$ Y3 l; b, C2 \" @ * E) i- o) m) \
, ~2 { v0 R3 T: } E' i( |9 @/ N 4)session
9 y3 s! I% {1 c, c x a,什么是session?2 `3 R) y0 Z! S q/ _- L! h3 {7 D' y
浏览器访问服务器时,服务器会创建一个session
5 R4 ]% Z9 R& H- K 对象(该对象有一个唯一的id, 一般称为sessionId)
: B) P; q% N4 y$ b" Y( z 。服务器在缺省情况下,会将sessionId以cookie" m# J- Z, l- z u0 A
机制发送给浏览器。当浏览器再次访问服务器时,
. j% `! s3 e9 ?- u- W- x 会将sessionId发送给服务器。服务器依据sessionId
& Q. U8 @9 c. D2 Y9 `/ @ 就可以找到对应的session对象。通过这种方式,4 ~% h& u5 t6 {/ N) x
就可以管理用户的状态。4 R0 s$ p8 G6 _- f: @4 K
b,如何获得session对象
) X3 }; S! B- m9 e) `% u 方式一:
5 l: I3 @5 a/ z4 n& J; y HttpSession session =
- j7 Q3 E0 S1 D9 } request.getSession(boolean flag);
: r$ O/ D# ?: u3 U) ^ 当flag = true:
$ \: W" z0 v' l# C3 @6 ] 服务器会先查看请求中是否包含sessionId," G7 ]2 ]+ N6 G. E5 ]3 P3 O9 x2 q) E$ @
如果没有,则创建一个session对象。1 `& h7 P8 M! `5 F; ? q/ o; R2 N
如果有,则依据sessionId去查找对应的
$ ]% C) P2 i$ `: E: w) B session对象,如果找到,则返回。
! h ?, X% q' P5 k2 ]$ i 如果找不到,则创建一个新的session对象。
5 R4 c' h, ^1 U; y 当flag = false:- e( f% S1 G% D9 j9 t* ~' y9 y
服务器会先查看请求中是否包含sessionId,
3 O. J! M5 w! F1 T8 L 如果没有,返回null。7 R: B1 C- W( r) R: n+ |) U
如果有,则依据sessionId去查找对应的' e3 K8 @4 F0 \8 ?( [: [
session对象,如果找到,则返回。
3 E& {/ m# B8 ^6 N2 J9 W' s 如果找不到,返回null。
. m* l7 S+ w* x: ?# g. @ 方式二:
6 v* u! o, u5 S O" O3 n HttpSession session =
( g+ Z1 J ~! z& C: D- g0 f request.getSession();
2 @0 @1 n' W0 D+ d7 U% N 与request.getSession(true)等价。
# @0 O5 `3 P* ^' F c,HttpSession接口提供的一些方法
0 g" A9 H( y) J+ J4 A( K% C1 g //获得sessionId。
: L1 p+ ]& ]4 `8 x3 L String session.getId();
! V: R3 a+ c5 G" Y //绑订数据 @9 n! V9 P2 s5 l" S, q1 `7 [
session.setAttribute(
- K. c$ ?* a/ v* E; |, \0 T3 ^1 H String name,Object obj);
. D A$ V/ H' y8 T2 l0 y( j2 b //obj最好实现Serializable接口(服务器
1 j9 e( i7 V) c( h/ z+ k# I 在对session进行持久化操作时,比如钝化
4 U% Z0 X. L+ t: D& ? 、激活,会使用序列化协议)。
4 _' M( e+ T* r& T! G Object session.getAttribute(String name);
6 T6 k1 h3 F3 ?1 s* c+ V% H //如果name对应的值不存在,返回null。 e# s- Y8 {; D$ {9 l M' J
session.removeAttribute(String name); \* C4 P* n1 _1 B ~6 Q. N% ?/ m
d,session超时$ l5 s, G: X" b# w! p+ W' n/ I
服务器会将超过指定时间的session对象
& C: F$ s7 ~& Y9 ?6 R* g 删除(在指定的时间内,该session对象没有3 X4 c' {: a4 D6 A; E. o
使用)。# P4 ^5 ]1 o9 Q( v
方式一:, U6 N. K- ?! ^
session.setMaxInactiveInterval(
+ m/ E0 z3 D: ?' F2 E' r, Y/ G int seconds);, i0 s X: G6 ?1 e! e
方式二:- U$ R5 J+ _5 }7 q' i: {
服务器有一个缺省的超时限制,可以3 `) W% Z$ [; @, D7 S5 `6 g% j9 |
通过相应的配置文件来重新设置。
) M- R5 n6 u9 z 比如可以修改tomcat的web.xml(+ b- j& @. m4 E' @% i+ y+ Z p2 v
tomcat_home/conf下面)。' O& c- P# K# \- I5 M9 p
<session-config>/ D8 m; ^( u0 A! w0 k
<session-timeout>30</session-timeout>
$ N% x1 |, M5 [7 `% q- X/ d </session-config>
, p' ^$ ]/ I/ w# O% A a! ?0 M 另外,也可以只修改某个应用的web.xml。5 x& e# I, j& g# `7 f9 `
e,删除session
2 u. W+ P' T6 S5 _ session.invalidate();
5 M2 E4 q8 ^! j( Z6 Q" ?) g
1 n- a* v4 i, V2 p% y 案例:
5 R: g4 g8 x: `9 {+ N3 g) E) f session验证5 ~0 w# l5 }( Y1 R; F# q
step1 在登录成功之后,在session上绑订一些数据。
9 n/ P# e1 O/ J" M; l 比如:9 q$ y" [+ d# L: t
session.setAttribute("user",user);& k0 k1 p1 Z% a; J0 w* E
step2 在访问需要保护的页面或者资源时,执行" |* G& t, @+ k2 N4 a, Y
Object obj = session.getAttribute("user");
' c+ k1 W5 f% ` 如果obj为null,说明没有登录,一般重定向到
' s( c; k0 T- h. r: E 登录页面。
, R6 f" K8 E/ V2 h, E5 d7 E$ R$ E |
-
总评分: 帮币 + 5
查看全部评分
|