该用户从未签到
|
状态管理! \% K! n7 q: m+ d6 N
1)什么是状态管理; H. S# S) D3 { b, Q
将客户端(一般是浏览器)与服务器之间的多次3 A2 g8 f/ F8 _) `& F
交互当作一个整体来看待,即将多次操作所涉及的3 O- l5 |1 U" m# U
数据记录下来。
2 U, I! X' t. e& r 2)怎样进行状态管理* o* K2 `1 q( r& Q: r) f! r, a
第一种方式,在客户端管理用户的状态: p7 a! J7 U% @$ q% U& Q1 ?
(cookie)。
, z) m8 v. I2 z; {1 P$ ^/ @ 第二种方式,在服务器端管理用户的状态
, i1 N% P, @% W7 o6 j (session)。
\ H; o4 D- C* k+ }9 a( z 3)cookie% ]/ y3 @- x1 V$ I
a,什么是cookie?
% j" J9 Y! Z4 K3 O( V7 x 浏览器在访问服务器时,服务器将一些数据
$ J7 M" V; P. f$ n1 m3 Y 以set-cookie消息头的形式发送给浏览器。浏览
) R% Z! V v8 ~2 p 器会将这些数据保存起来。当浏览器再次访问/ s, M( F$ q" w% ~/ d# p# |
服务器时,会将这些数据以cookie消息头的形式- [! C/ k7 D8 V" Q2 S( M
发送给服务器。通过这种方式,可以管理用户的+ g* [& I. ?* s/ y7 i! @8 L
状态。: |8 f6 u' M2 K# R7 |4 w. K
b,怎样创建cookie?
9 }, V0 i- W) S( l( X Cookie cookie = new Cookie(String name,
( w! S9 P' A6 ~: y) s6 o String value);
; t. q. ~& P' q2 D! H7 n& i2 Y response.addCookie(cookie);
" W4 M9 M w- d c,查询cookie
! {" S7 w T9 z- k //如果没有cookie,则返回null。3 I: S, r4 G2 z
Cookie[] cookies = request.getCookies();7 w. O A' h& u$ x K: }4 E/ j
String name = cookie.getName();
% p9 ]4 I. x) q String value = cookie.getValue();
5 R# b5 n# Q8 k" [ d,cookie保存时的编码问题/ T) m; _6 _- u
cookie的值只能是ascii字符,如果是中文,4 a* |/ Q# G9 ~0 r; v
需要将中文转换成ascii字符形式。( K6 n, C9 q+ K, e0 ?- B
可以使用URLEncoder.encode()方法和
& T1 \' m! A# P3 b# h Q# | q+ f4 _ URLDecoder.decode()方法来进行这种转换。
$ r" j" m4 W3 g! p: A e,cookie的保存时间8 ~( q$ P! ] C% c3 X! f
cookie.setMaxAge(int seconds);: ]7 Y' h+ a9 f
seconds > 0:浏览器会将cookie以文件的方式
% y5 z/ M O9 i8 s' M& W/ z8 ] 保存在硬盘上。在超过指定的时间以后,会删除
$ c% f7 S+ h3 U- Q: \ 该文件。. M8 H9 Y( F9 W, N' G
seconds < 0:默认值,浏览器会将cookie保存& z( u r. t. }6 i7 l
在内存里面。只有当浏览器关闭之后,才会删除。0 E/ [8 u R p- p2 X! R
seconds = 0:删除。8 A9 x p' e3 d' s! D6 h p, F2 L
f,删除cookie1 \! w( A" R' n
比如要删除一个name为"username"的cookie。8 h7 D1 {, c- e5 V! U
Cookie c = new Cookie("username","");
1 v, I9 p+ x$ ^: p' W4 Z. q c.setMaxAge(0);8 ^, Y# @7 l3 g& G( F) ~. ?/ q
response.addCookie(c);
( j" `5 v4 h, u+ A5 y g,cookie的路径问题
3 c9 ?. g$ P1 P P' U 浏览器在向服务器上的某个地址发送请求时,3 [) x- Y3 z7 y) T4 i
会先比较cookie的路径与向访问的路径(地址)是- l6 j; k$ [ q, u& Z' {' r
否匹配。只有匹配的cookie,才会发送。9 ^7 I3 d0 v4 q; M% Q5 @
cookie的路径可以通过. \/ M$ R- R7 _5 J2 X7 Z
cookie.setPath(String path)方法来设置。$ c1 D( A/ j& b
如果没有设置,则有一个缺省的路径,缺省的# N0 T. [0 L" r
路径是生成该cookie的组件的路径。+ ^; e: a7 v+ m: c0 k+ \- @
比如: /appname/addCookie保存了一个cookie,
; A+ o+ D9 O8 D3 s0 Z* E, ]/ e! D 则该cookie的路径就是/appname/addCookie。8 V( F) l/ Z+ M' C
, Y! S# u1 L9 p6 H5 S8 h4 f 规则:
5 W2 D- C( p* L% @2 a, V cookie的路径必须是要访问的路径的上层目录' H8 ^; y" D! V: c( R; M
或者是与要访问的路径相等,浏览器才会
9 v8 k( E! B& n8 M- e 将cookie发送给服务器。; j2 y+ e. O& ?8 |9 M
9 ] D) }; c* h+ N8 Y$ M
一般可以设置setPath("/appname"),表示访问
# b) ^$ s' p: c' G. W 该应用下的所有地址,均会发送cookie。# q% V1 N! I3 R' h% g2 g5 S: Q4 L
h,cookie的限制 Z6 ?1 l9 a1 c! r+ k
cookie可以禁止
( Z% A, T- n; Z/ ^5 W7 j' D cookie的大小有限制(4k左右)
6 s0 _6 {) V& J, l/ }- s cookie的数量也有限制(浏览器大约能保存300个) ; }! y$ i! `3 Q ^. V {" g2 Z
cookie的值只能是字符串,要考虑编码问题。
3 x. r' ^) F8 L" Q! r; M$ o, ` cookie不安全
" v. g( t, @( A3 F 练习:9 x' z9 d2 v6 ~9 j
写一个Add_FindCookieServlet,该servlet先查询) s u" ]7 b# {4 ^9 u
有没有一个名叫name的cookie,如果有,则显示; W0 i/ T3 F$ b4 P1 U
该cookie的值,如果没有,则创建该cookie($ H/ t5 j8 ~) u
cookie的名字:name,cookie的值:zs)。' s9 L! U! f5 i
1 k. \0 C7 z4 D) p
+ x) T( [8 n/ c0 {. J0 [) e 4)session # R7 {# h" ~" }5 N* D3 t
a,什么是session?
6 Y! }, k3 X* `( y0 E) y 浏览器访问服务器时,服务器会创建一个session
" v: p# Z0 {! T/ V1 m 对象(该对象有一个唯一的id, 一般称为sessionId)
) d5 E7 o0 W5 G$ S8 L 。服务器在缺省情况下,会将sessionId以cookie
8 ^; l1 K* y0 ], a 机制发送给浏览器。当浏览器再次访问服务器时,
& z }. I: U9 c) ^/ ?# A. H 会将sessionId发送给服务器。服务器依据sessionId
4 S+ I; w: {& p- \) H 就可以找到对应的session对象。通过这种方式,
f. D) B9 V$ \0 p8 A5 p$ ~1 [# ~ 就可以管理用户的状态。
' y n! Q/ p$ n& U% D: \7 i6 L8 x b,如何获得session对象
% K3 s( D; y; W& z5 c 方式一:
# ]. _; }& ]" B- g0 _4 ] HttpSession session = ; J; T4 W1 R% Z- r! V, F! J! g7 k
request.getSession(boolean flag);0 \" G I% ^- c$ {( I1 d, |2 j# F6 B
当flag = true:8 R# N8 O8 H4 \) D8 s% @4 v7 w4 X
服务器会先查看请求中是否包含sessionId,1 C% G* c) i( |
如果没有,则创建一个session对象。; N& c" g6 W# M6 ]/ J+ d n7 {/ Y
如果有,则依据sessionId去查找对应的# C; }' r1 ?0 T/ y f2 \
session对象,如果找到,则返回。( D, D. H) c* c- R
如果找不到,则创建一个新的session对象。
2 L! A- D) M& E3 b) y- Z$ B1 y 当flag = false:
, o1 I. q! }5 S8 o* \( a 服务器会先查看请求中是否包含sessionId,
7 A) r- f$ b. u9 r- K/ S 如果没有,返回null。
3 U5 C9 r$ G, h; y( |1 ^ 如果有,则依据sessionId去查找对应的
8 b1 {: X% i: V$ d& ~. c5 \ session对象,如果找到,则返回。: ^2 Z# I f$ O8 Z2 r
如果找不到,返回null。' l0 p. X# V+ ]# E
方式二:
$ A: {/ Q- x" c4 c HttpSession session = $ f4 }- Z( k; N+ f( q* Q: Y. t
request.getSession();
% O' ]( Z$ F$ d" W, Z3 n9 H7 \4 c 与request.getSession(true)等价。' L. m9 a! q: p) K) K
c,HttpSession接口提供的一些方法
+ C w1 ~) o7 U" v. Q: p' u //获得sessionId。6 j4 O4 \7 L$ r3 `4 z- J
String session.getId(); \! H+ k: H8 \6 a5 p9 B
//绑订数据" g; M* C) ?0 A
session.setAttribute(
7 Z8 [. Q' ~. W4 P7 [3 O" w* C String name,Object obj);& N% R! ` F' U# _6 |" V
//obj最好实现Serializable接口(服务器
, d, f9 X; {, N1 |7 G8 ~# }3 ` 在对session进行持久化操作时,比如钝化$ S% T) \# Y) L4 s, ]+ K/ B7 |& `
、激活,会使用序列化协议)。
1 A5 _( K0 v% F9 Y, ? Object session.getAttribute(String name);
4 ?6 I9 I$ q O+ o //如果name对应的值不存在,返回null。
# F9 c2 m' p1 i" g session.removeAttribute(String name);$ j# U, _$ f' y5 L, Y6 y: r
d,session超时' k6 ~- H; b* I( V) B9 i: A
服务器会将超过指定时间的session对象2 X; U- t" B9 X0 m( N* O( y
删除(在指定的时间内,该session对象没有
8 r. G6 \8 b6 u* a) w# V7 @5 A 使用)。
( T6 K6 _1 m$ u2 o5 e 方式一:
& z: U7 O' D) u) o) l session.setMaxInactiveInterval(
8 C' b; u$ _1 z: q. q) I; O int seconds);9 E; w+ Z, v$ `5 h
方式二:
) E% L2 M8 x ^. ` 服务器有一个缺省的超时限制,可以# ]# m, |5 ^+ M; \; h
通过相应的配置文件来重新设置。0 _3 O. D/ S: S2 W3 S3 ?' b
比如可以修改tomcat的web.xml(: Z8 i: {' W8 P
tomcat_home/conf下面)。0 V0 F1 c* O {2 b" {
<session-config>0 R7 n2 a$ b9 v6 t" V; Q% ^
<session-timeout>30</session-timeout>
3 o& [' u- s4 t4 V) J) B </session-config>
8 K6 g8 A8 J' i" _5 Y- e 另外,也可以只修改某个应用的web.xml。# l9 n+ R5 g# L. P G Q9 ?
e,删除session' l5 W3 ~# f' f4 ?# |, [
session.invalidate();
0 \& V% U" \* @+ v6 P
0 Q/ e' {1 `' ~/ \8 d" i" ? 案例:: r9 V" Q, i0 z
session验证
1 a B2 ?/ w0 L) K0 o- L step1 在登录成功之后,在session上绑订一些数据。
1 S3 i! z ]/ h8 A5 x5 z U: E2 ~ 比如:! Q7 J6 ^- `. O; N; O5 p
session.setAttribute("user",user);
2 T6 }& Z9 P+ n& y& _+ s step2 在访问需要保护的页面或者资源时,执行
$ }( m2 a5 D3 B- G Object obj = session.getAttribute("user");) {6 [7 f! ~- | D
如果obj为null,说明没有登录,一般重定向到" X2 T, s9 Y6 w
登录页面。
5 W2 W) @; W8 H4 r9 ?0 w2 l
# O3 d6 W; Q, P+ e7 c8 o' K: \" ` |
|