该用户从未签到
|
2、状态管理
7 a, e: X' P# z2 T* m 1)什么是状态管理
! @! g7 u# [& n* z' O" z$ B7 M! ~ 将客户端(一般是浏览器)与服务器之间的多次
6 A% B( l. T- {% X) ^+ c/ h, B! L 交互当作一个整体来看待,即将多次操作所涉及的0 N* q8 P' b. C
数据记录下来。
0 i, j/ G% u7 m! W7 z& u" Q 2)怎样进行状态管理
$ a. ]% X3 [( v6 [! ?. p9 E 第一种方式,在客户端管理用户的状态
2 Z2 t* K q( K- s2 [ (cookie)。+ R( C6 ]+ s+ N: L1 X8 k
第二种方式,在服务器端管理用户的状态$ Q# P( w) U5 r# g' h- o. [! L! C" z
(session)。
! G2 h3 |5 z2 s 3)cookie
8 u# F" J2 V7 {2 m0 w" @$ V: B$ ` a,什么是cookie?
/ O% d, I/ t2 ^/ |3 n 浏览器在访问服务器时,服务器将一些数据/ _1 Z! E; Q6 M3 z9 s! s
以set-cookie消息头的形式发送给浏览器。浏览& J0 w4 c% K( [) X
器会将这些数据保存起来。当浏览器再次访问
& B6 Z' K" O6 H2 ?* _4 `8 v 服务器时,会将这些数据以cookie消息头的形式
4 t2 e q Q9 j 发送给服务器。通过这种方式,可以管理用户的" x. `! u' q+ S+ e' }$ d/ `: ~
状态。
, U- \( q% _8 r* d O. x, E b,怎样创建cookie?5 M! L: H' ]: [0 t! U' t8 j
Cookie cookie = new Cookie(String name,# S* f& M! x5 u: E
String value);- _. f3 `9 E# q; Q7 y
response.addCookie(cookie);+ ~4 y/ a! J. s2 |! P
c,查询cookie) v2 z' f$ g3 M4 ^: `) J# m$ F2 v
//如果没有cookie,则返回null。
, n6 P0 b: V% Z: s( y2 p Cookie[] cookies = request.getCookies();, |# s- F+ ~6 q/ v! Z2 N6 T
String name = cookie.getName();$ s1 m. m5 B/ D [
String value = cookie.getValue();0 l6 {8 J. N! w
d,cookie保存时的编码问题, |5 z0 D8 {/ H8 y1 `3 z7 l' X
cookie的值只能是ascii字符,如果是中文,
$ L' z: G J1 @7 y' Z 需要将中文转换成ascii字符形式。
o; w a/ z6 P* ~* f 可以使用URLEncoder.encode()方法和
. d' u" l7 I, L( Y& M URLDecoder.decode()方法来进行这种转换。1 ?5 }* j& P. V1 i/ T& V4 z
e,cookie的保存时间
+ L! c y' D, N, \1 J# ^6 {9 @ cookie.setMaxAge(int seconds);
+ S/ I" \: v+ y' M! A! R seconds > 0:浏览器会将cookie以文件的方式
8 q& q! h0 N3 o- v9 T 保存在硬盘上。在超过指定的时间以后,会删除
0 ~$ Q* L3 D/ n' U* T* O# v" X 该文件。% l& t: }2 U% X: H
seconds < 0:默认值,浏览器会将cookie保存
% m |; k4 T: J) W- ~9 f4 B 在内存里面。只有当浏览器关闭之后,才会删除。
8 F" I# E: H& M6 o6 G2 e# ] seconds = 0:删除。
4 V5 L% k: Y- x% \/ h+ J f,删除cookie+ w- s. q, f6 o: d1 Q: }. _% {, m
比如要删除一个name为"username"的cookie。/ T5 L9 b# T$ F" s6 m$ w
Cookie c = new Cookie("username","");
, o5 c' F) U0 t( t: R c.setMaxAge(0);
/ Q0 v+ l9 ]# R$ J response.addCookie(c);* I- g) E( g& h2 o$ i
g,cookie的路径问题
* g* J* _" R3 ~ 浏览器在向服务器上的某个地址发送请求时,
+ e0 V0 o- g: U; @1 H 会先比较cookie的路径与向访问的路径(地址)是0 V9 U7 [# _- Y) |* }: H1 c! {* U
否匹配。只有匹配的cookie,才会发送。: h5 E1 t3 |# Z3 R/ I* t* Q. r
cookie的路径可以通过
, t- g4 F& n: u- p1 a$ Y/ d9 V cookie.setPath(String path)方法来设置。
6 Z7 }. O# g) Y: D$ i 如果没有设置,则有一个缺省的路径,缺省的5 b' X% }5 U+ H5 O' Z# u' H% z
路径是生成该cookie的组件的路径。
$ X" T; K: |! u6 L9 i 比如: /appname/addCookie保存了一个cookie,) I, ^ C5 w. d$ o* {6 L5 C
则该cookie的路径就是/appname/addCookie。; A3 @+ {" p# K& [; g' H
4 y# a P( s; u5 b$ i @ 规则:+ l7 r+ w& z% |) y! C
cookie的路径必须是要访问的路径的上层目录& ]$ f& j. H% U
或者是与要访问的路径相等,浏览器才会
! q% }" ?% _) w& m$ D 将cookie发送给服务器。
+ @- F1 _8 W9 Q" z 7 V1 |2 |+ `2 k# H4 L3 O- n: w( {
一般可以设置setPath("/appname"),表示访问+ v) e7 y5 K$ C
该应用下的所有地址,均会发送cookie。. t; G% r: _5 S' S- T+ k
h,cookie的限制
5 N J8 @( q9 {6 F) C cookie可以禁止
- l5 K- z' U3 ]) W5 c/ O cookie的大小有限制(4k左右)
3 o5 m5 ]6 J! K2 E1 y% S' ` cookie的数量也有限制(浏览器大约能保存300个) 8 j: a0 u$ H, H U; i' ]. d
cookie的值只能是字符串,要考虑编码问题。
: I8 y# b0 H+ e" L9 g cookie不安全
3 G# }% W5 {+ k, w 练习:
$ U# @4 |2 s, a: R4 ?7 @) u 写一个Add_FindCookieServlet,该servlet先查询1 J8 \( j# q7 e9 d, F+ t
有没有一个名叫name的cookie,如果有,则显示3 F# X9 I% v5 O5 Y& L4 X, P
该cookie的值,如果没有,则创建该cookie(
3 m& F# D5 C: S3 [; T cookie的名字:name,cookie的值:zs)。7 N5 f0 i9 S/ G" J
+ v. ?* Y" m5 A7 f# L
0 l1 V, r0 ^' [6 | 4)session
+ w* C' K' U& W/ e8 C4 r) p a,什么是session?' g& X5 E6 A8 X' F1 I* P+ u
浏览器访问服务器时,服务器会创建一个session- ~4 ~1 h4 _: p6 M. r" ]
对象(该对象有一个唯一的id, 一般称为sessionId)0 x& }: b n& ?* u% C0 X# B4 {
。服务器在缺省情况下,会将sessionId以cookie
2 P- r9 O3 ]( y9 \! l6 T+ w 机制发送给浏览器。当浏览器再次访问服务器时,
! C( ?$ T/ p; @: ^/ ]7 R/ i, v 会将sessionId发送给服务器。服务器依据sessionId1 ?1 I# m7 ]3 c8 D
就可以找到对应的session对象。通过这种方式,
" g5 R/ b; I5 J6 e 就可以管理用户的状态。
' Y4 a6 Z- ~6 f- S4 s) | b,如何获得session对象
4 b; O6 @: |& G' a% O6 @ 方式一:
3 ~: s$ y4 w$ \* G1 \ HttpSession session =
6 s5 ~( w& l7 I( f+ v request.getSession(boolean flag);0 d* V1 M8 S- U! y
当flag = true:
$ f4 U: Q# l4 t 服务器会先查看请求中是否包含sessionId,/ T/ ? W- w+ {1 ^& S
如果没有,则创建一个session对象。
; `1 X4 W: U* A0 v1 F: N 如果有,则依据sessionId去查找对应的
* J1 c/ {& C* M4 k' s session对象,如果找到,则返回。 t3 A* Y6 I6 B2 i: N/ P
如果找不到,则创建一个新的session对象。, L/ ^) D* r; c, X
当flag = false:
& m( r- p3 z" T' |. H4 ^ 服务器会先查看请求中是否包含sessionId,
: h& e0 V: Y. O 如果没有,返回null。
0 Z% F7 f& Y6 a/ Z% P: A 如果有,则依据sessionId去查找对应的7 A' _; E4 T- `# j) n0 h
session对象,如果找到,则返回。5 X" Z! z; h" w5 Z+ Q S( z" ~) U. c
如果找不到,返回null。+ u! e. ^1 s7 U* L) ?2 H
方式二:4 `4 O1 E, d5 ^) P. x
HttpSession session =
1 Q3 w* F" ~4 `, l h9 Y' Z request.getSession();
. p. Y d! w! j( x% a. H& y# S+ _ 与request.getSession(true)等价。1 e6 o- H, J$ v9 R6 v5 x/ k3 g
c,HttpSession接口提供的一些方法
G' ?& t( t! ? [; z4 e //获得sessionId。7 i$ l T9 Q9 }) t9 Z; [7 D
String session.getId();
" J1 Z8 f/ x$ H //绑订数据
; L& y7 y+ S2 s$ e session.setAttribute(: L& i' S1 u. X4 B6 D5 b
String name,Object obj);( R9 `7 c2 u, ^# {
//obj最好实现Serializable接口(服务器0 P$ P! ~9 C! U4 i% e4 f7 g
在对session进行持久化操作时,比如钝化# \) t4 c8 {" u! R
、激活,会使用序列化协议)。$ M' Q8 z ]) w4 }4 s7 N! z" g- p
Object session.getAttribute(String name);$ L3 I) Z, l9 I4 t. P- P; a
//如果name对应的值不存在,返回null。+ R" h7 r1 J' {
session.removeAttribute(String name);
, `) G6 ?: P5 I: ^2 N1 T- l# p _ d,session超时4 k: t5 K8 u% W" ]# P
服务器会将超过指定时间的session对象
( R! T: j7 t" y! m# v# k 删除(在指定的时间内,该session对象没有
+ W8 }/ M0 f) V3 w$ {1 s 使用)。
: W! O( ]0 I1 D) {9 P 方式一:
# g: L1 p# D6 u, s" k session.setMaxInactiveInterval(
8 t& r. u3 n1 u/ Q% y0 A1 G int seconds);
% g9 }3 w' L& B2 g 方式二:0 i# k; l) `+ C1 v2 w/ |
服务器有一个缺省的超时限制,可以
# A: W1 m }0 g4 w% h( u8 y 通过相应的配置文件来重新设置。! R; _* ~% V1 N- Y5 t, T7 g
比如可以修改tomcat的web.xml(* c) P) r/ h3 T0 |/ e
tomcat_home/conf下面)。
- v2 C' f" m* j* I: Y# T <session-config>- [4 J' T/ K( r8 k2 E
<session-timeout>30</session-timeout>( ]$ f, G, K9 [7 E* C, I; V9 e* }
</session-config>
$ j! a$ b2 w/ u3 a L/ U/ M 另外,也可以只修改某个应用的web.xml。
, \! @' @( R; v& o3 v! O5 G e,删除session
) m6 e' H+ k9 h, M session.invalidate();- A8 Y- }9 U! u- Z3 z
* r' p3 D% a3 w& c
案例: s- N# W8 f6 P
session验证. e) P7 Y* e7 J4 S6 C
step1 在登录成功之后,在session上绑订一些数据。$ _7 I( C# O9 v0 }
比如:: ?) Y9 A9 O* j, S3 ]4 o
session.setAttribute("user",user);
4 K: Q* _# X5 u5 G0 J: O step2 在访问需要保护的页面或者资源时,执行
s- Y5 ?$ T. c2 g* s' O Object obj = session.getAttribute("user");
, ?; M5 Z1 }: B2 U$ W! T+ i' x 如果obj为null,说明没有登录,一般重定向到
8 \2 F/ S; {% U p/ d 登录页面。 {! X# P- L9 C; c9 C6 |
|
-
总评分: 帮币 + 5
查看全部评分
|