我的日常

登录/注册
您现在的位置:论坛 盖世程序员(我猜到了开头 却没有猜到结局) 盖世程序员 > java状态管理 cookie和session详细介绍
总共48087条微博

动态微博

查看: 3696|回复: 5

java状态管理 cookie和session详细介绍

[复制链接]

326

主题

72

听众

999

金钱

实习版主

该用户从未签到

优秀版主

跳转到指定楼层
楼主
发表于 2014-03-18 12:40:02 |只看该作者 |倒序浏览
2、状态管理$ B. A8 s5 y( q. D& d3 k
1)什么是状态管理
( T  M* p# C5 d  将客户端(一般是浏览器)与服务器之间的多次
! T( @7 _8 ^8 W% G* n 交互当作一个整体来看待,即将多次操作所涉及的
$ V1 h1 T6 U2 g8 K+ S  n' @ 数据记录下来。
( w) H) G5 q) _* A8 Y* G 2)怎样进行状态管理
0 w- _$ C4 M( K2 K: q/ N# c  第一种方式,在客户端管理用户的状态4 ]8 t6 q4 l/ L; c% H+ W
  (cookie)。  P0 u; ]& K- v( w* N1 I, @3 J
  第二种方式,在服务器端管理用户的状态% N; {# ]& K( B) Q, p2 Y
  (session)。
; w! z: X8 X% h/ g+ Q3 M3 J' d0 b. W 3)cookie/ S) n/ h, T  ^- }  `0 |
  a,什么是cookie?* r6 s0 X5 @# Y
   浏览器在访问服务器时,服务器将一些数据$ G5 k3 j: {* s% S, |- p& I' l
  以set-cookie消息头的形式发送给浏览器。浏览
% F& {+ T; t1 d& F9 ^7 O, e  器会将这些数据保存起来。当浏览器再次访问) e7 F" s2 k8 x  @; X) a6 M
  服务器时,会将这些数据以cookie消息头的形式4 T; L0 r- m% K( @$ b# j6 c
  发送给服务器。通过这种方式,可以管理用户的4 q5 a. Z! J9 x' w0 Z( Y
  状态。: W9 L/ j) w8 ]5 G
  b,怎样创建cookie?
0 L% U. ?5 e8 _: T   Cookie cookie = new Cookie(String name,0 p2 g% a  b% l; D3 N
   String value);1 }( g9 v! L( i' C# K  y5 @
   response.addCookie(cookie);
3 t* ?4 s  L# ^  c,查询cookie1 |# X, O9 D% L. T6 f
   //如果没有cookie,则返回null。. R7 M1 Z8 G: L- p
   Cookie[] cookies = request.getCookies();
# K) |6 R8 l7 q+ l4 L   String name = cookie.getName();9 Y% r# K1 y* h7 [3 A) X* ^# f) K
   String value = cookie.getValue();
! h' G! j7 e8 O  d,cookie保存时的编码问题
1 m; M: A" U! g+ t! L# O- ?   cookie的值只能是ascii字符,如果是中文,
  e! ?5 Y  K" e; I6 ~' }8 e. J0 s   需要将中文转换成ascii字符形式。
# f  K3 Z& M/ X   可以使用URLEncoder.encode()方法和# l3 K  s+ o- H- C; S
   URLDecoder.decode()方法来进行这种转换。
% {- j2 A- ~. x% k6 N# S6 a# K3 C; v' x; K  e,cookie的保存时间
" Z6 G/ l/ }- ^' c1 D1 b8 ~' M   cookie.setMaxAge(int seconds);
9 Z) h  \' x5 N3 L9 J  G2 e   seconds > 0:浏览器会将cookie以文件的方式3 a# Q' y$ J" Y2 G$ a& k/ r- S
   保存在硬盘上。在超过指定的时间以后,会删除
" j; X* [) g/ H2 H   该文件。
3 j0 e3 |* L& e5 c6 X( ~. _   seconds < 0:默认值,浏览器会将cookie保存
- Q& F0 k; \% s   在内存里面。只有当浏览器关闭之后,才会删除。
7 V- |! `% S2 f) j( N   seconds = 0:删除。
: q3 u9 i' ?0 ?2 }- z  f,删除cookie
$ O7 j8 a6 u1 U# Z   比如要删除一个name为"username"的cookie。
! V1 p5 v* F& U) ^$ m4 ~$ Q. ?   Cookie c = new Cookie("username","");
7 G# W: ^3 e* o0 r   c.setMaxAge(0);
7 j7 @% O! S2 ?9 K$ f& F3 @1 _   response.addCookie(c);
3 _# l5 u7 n: Q6 _, J  g,cookie的路径问题
6 d6 `0 N2 m# g+ \0 |1 J; R& r) b1 |   浏览器在向服务器上的某个地址发送请求时,
4 Q8 `  n3 r" ~5 H6 ~( Z  会先比较cookie的路径与向访问的路径(地址)是
* g7 M+ A* K0 S4 T1 ]& R7 @  否匹配。只有匹配的cookie,才会发送。
1 x) T; c) \4 P4 V( e   cookie的路径可以通过+ t$ [" s& v) ~+ L
   cookie.setPath(String path)方法来设置。
8 L6 l+ J( e, @3 }7 S- h2 h   如果没有设置,则有一个缺省的路径,缺省的+ M7 s- o8 S! _& a+ J, t
   路径是生成该cookie的组件的路径。2 M) b" ?2 b2 l$ @
    比如: /appname/addCookie保存了一个cookie,8 T( B! v% |6 \) h: T3 y" J
   则该cookie的路径就是/appname/addCookie。
1 T9 n" y5 v8 V' o$ g4 W   + r: O+ F( q' |5 j- }
   规则:! E, d1 B: V" G+ X7 _' C
    cookie的路径必须是要访问的路径的上层目录( n: i  `; L. t7 ~' T3 \: J# Z
    或者是与要访问的路径相等,浏览器才会; d. t5 _' ?  v& O# V
    将cookie发送给服务器。3 e# q" G0 L4 C$ }+ @& ^
    / }4 |: `+ I+ c% Y$ B& F
    一般可以设置setPath("/appname"),表示访问- H4 u+ N, n1 O8 S5 ]) R  |! r- M
    该应用下的所有地址,均会发送cookie。
/ B/ d# Q# _5 h9 Y. z' {  h,cookie的限制
( C' @* d( G0 |1 v+ ?   cookie可以禁止, F4 R: q3 S5 B* x3 U# A
   cookie的大小有限制(4k左右)
' L/ g1 R# A6 S$ C; a  g7 R) v   cookie的数量也有限制(浏览器大约能保存300个)
) N6 `9 |6 l" m5 ?   cookie的值只能是字符串,要考虑编码问题。+ y2 z# C  Z7 `/ F$ Y* P* I. M. m$ _8 n
   cookie不安全
. S( i3 h0 K) I2 t0 l- X" s 练习:2 S4 I& Z& h" B' r5 p* h3 |+ F
  写一个Add_FindCookieServlet,该servlet先查询3 e/ L& @4 Q! D5 T) p
有没有一个名叫name的cookie,如果有,则显示
7 J( W, s7 G6 D7 s- I 该cookie的值,如果没有,则创建该cookie(
& Q1 }7 w1 B! C8 Y/ F2 P; _8 I cookie的名字:name,cookie的值:zs)。# o9 d1 c9 r- z
  0 y& z  D6 {: I: o* `; a
  / a& D6 M' |( |( m0 Y. M2 Z  a* `0 Y
4)session
5 k1 @2 `7 v# r# M) D" R  a,什么是session?7 Q: f0 }: U1 I! F* p! N
  浏览器访问服务器时,服务器会创建一个session
' _8 ]! ^6 x% G& D  M) Q  对象(该对象有一个唯一的id, 一般称为sessionId)
9 y& s0 T. v1 R, G. G$ j" T' h& Q  。服务器在缺省情况下,会将sessionId以cookie; S0 d6 }2 F, m- l
  机制发送给浏览器。当浏览器再次访问服务器时," |0 }) u( |! \4 |% X
  会将sessionId发送给服务器。服务器依据sessionId
/ _9 ~$ u* t# t9 d  就可以找到对应的session对象。通过这种方式,. T9 S" M' u6 |: a# v8 w+ T
  就可以管理用户的状态。
7 g5 Q4 ?, q8 W  b,如何获得session对象
3 |% o+ z4 u2 `' j4 I   方式一:% ?% X5 Y# S" d; q+ w- Q6 ]
    HttpSession session =
' r8 ]2 l8 G4 {6 r4 U1 k: l    request.getSession(boolean flag);
' H( V' ~3 {7 r3 M+ K9 F    当flag = true:
/ I! @. j& E! S+ S6 x     服务器会先查看请求中是否包含sessionId,
( E5 _4 L( }; J' I; D     如果没有,则创建一个session对象。! |. J2 `' h$ r- Z- e# _' a
     如果有,则依据sessionId去查找对应的
) t/ P9 s5 V; k% L: [( X     session对象,如果找到,则返回。8 O% z# ~& I% ^9 L/ C
     如果找不到,则创建一个新的session对象。3 A8 |% Y4 a0 `7 M' r( t- p' m
    当flag = false:
" a. ^. ]" d+ E* a9 t     服务器会先查看请求中是否包含sessionId,4 S. u4 C' _3 ?# w+ q
     如果没有,返回null。- I7 q5 i) F' w2 @7 l0 y" u
     如果有,则依据sessionId去查找对应的; H2 B$ g3 _* F; Z
     session对象,如果找到,则返回。
; K. u" Y  `4 ~2 U5 K: ?& x     如果找不到,返回null。
' b2 F6 L, m' s4 J   方式二:& I3 ~: G/ m! {" S, i
    HttpSession session = ' w: t5 C9 D: _: s: e
    request.getSession();
7 c  H7 |2 E% q+ t& z    与request.getSession(true)等价。
0 Y) s3 X- ~% U0 V- g  g  c,HttpSession接口提供的一些方法
7 n! }+ N! |5 s8 B, }" \" z+ p    //获得sessionId。( f* h' A5 O. d, a7 B& v$ O+ J: z% w8 ^
    String session.getId();: j8 l  [+ b0 s! K! h! `( k# o
    //绑订数据3 S: c0 i% o: H3 v1 R# n
    session.setAttribute(- H" J; o6 K5 h$ t. a% e+ ]
    String name,Object obj);* p- f5 u8 A; t& K' O
    //obj最好实现Serializable接口(服务器* d" J1 E- n8 ]6 s" d
    在对session进行持久化操作时,比如钝化
( f0 b4 }1 {* G    、激活,会使用序列化协议)。
; V) T& x& W+ G  W; s; t    Object session.getAttribute(String name);
) k" O$ u1 i9 T; U% H    //如果name对应的值不存在,返回null。$ D' f) ?6 H8 z" D; D
    session.removeAttribute(String name);
8 O, \6 {2 Z  o9 N" t2 R  d,session超时
& d3 M3 E  j5 [0 o8 g    服务器会将超过指定时间的session对象
3 q# F. }, L7 w! W. |* p! J/ y   删除(在指定的时间内,该session对象没有2 X# k% n; A+ c- ~. J$ P
   使用)。  y, z) I8 ?0 q
    方式一:
! m+ _' w! s. A7 ]. C+ M" f/ _- S8 x     session.setMaxInactiveInterval(9 p7 I8 j/ q* }+ a0 i
    int seconds);
, k2 ^! M9 D: p1 R+ d; A* T2 U    方式二:
1 L+ G+ t% C. q* |% H+ d) H% ]     服务器有一个缺省的超时限制,可以7 K; C: I  d3 v* O+ K: W/ p( `
    通过相应的配置文件来重新设置。
; s9 S  g4 k- S1 U) u& ]/ P     比如可以修改tomcat的web.xml(
& }! l2 G) L& p/ K6 y) V3 y" K/ y3 S     tomcat_home/conf下面)。
! Z5 w& D4 W! z. W0 {- j; z. q" l9 O8 E2 L     <session-config>
$ g% r( N6 S  ]& b2 C; Q; x7 k5 y          <session-timeout>30</session-timeout>7 K$ [- q. u) V1 g/ D
       </session-config>
* I! x( V; U- M: G4 I4 W    另外,也可以只修改某个应用的web.xml。
/ q  X/ @8 o; z# {( v. B! O  e,删除session
9 P2 E( |5 i, i9 S   session.invalidate();
# s/ t3 b6 u4 _2 K3 l   
( {5 {* x5 f, l; x6 U, ~ 案例:
1 w7 o) W( t/ S+ g  session验证
7 ~/ @0 {8 `* n9 ], A& ]( I  step1 在登录成功之后,在session上绑订一些数据。  @- w2 t: y, r$ x/ [& @
比如:
8 p- j. M! T9 B6 H5 h  session.setAttribute("user",user);+ C7 q- j) ~8 z  a2 i! C5 R* a2 a) E
  step2 在访问需要保护的页面或者资源时,执行
3 e+ q9 P! z' B& t7 Z) T  K4 i' W  Object obj = session.getAttribute("user");
5 l) _4 f+ }' B8 G$ L3 a- v. D  如果obj为null,说明没有登录,一般重定向到
6 Q( R8 w7 T; [* F  登录页面。9 C+ Q9 Y1 W7 S, }# t; Y# j

科帮网 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与科帮网享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、科帮网管理员和版主有权不事先通知发贴者而删除本文


JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

已有 1 人评分帮币 收起 理由
蓝色经典 + 5 赞一个!

总评分:  帮币 + 5         查看全部评分

2

主题

0

听众

148

金钱

三袋弟子

该用户从未签到

沙发
发表于 2015-10-15 13:48:37 |只看该作者
看了看  学习学习  哈哈哈哈
回复

使用道具 举报

1

主题

3

听众

341

金钱

四袋长老

该用户从未签到

板凳
发表于 2016-03-17 21:56:00 |只看该作者
' p9 N% |' m1 X
学习一下。谢谢
回复

使用道具 举报

woniu 实名认证   

2

主题

0

听众

330

金钱

四袋长老

该用户从未签到

地板
发表于 2016-04-12 12:20:20 |只看该作者
这个项目太棒勒!下下来学习下!
回复

使用道具 举报

5

主题

1

听众

54

金钱

二袋弟子

该用户从未签到

5#
发表于 2016-04-18 17:15:32 |只看该作者
以前不太理解,现在看了后,明白了很多
回复

使用道具 举报

5

主题

0

听众

316

金钱

四袋长老

该用户从未签到

6#
发表于 2017-08-14 08:31:08 |只看该作者
不错不错不错
回复

使用道具 举报

快速回复
您需要登录后才可以回帖 登录 | 立即注册

   

关闭

站长推荐上一条 /1 下一条

发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
快速回复 返回顶部 返回列表