当前位置:文档之家› 深入理解ServletJSP之Cookie和Session原理

深入理解ServletJSP之Cookie和Session原理

由于H T T P协议的无状态特征,W e b应用中经常使用C o o k i e和S e s s i o n来保存用户在与系统交互过程中的状态数据。

下面通过分析H T T P协议对C o o k i e和S e s s i o n的工作原理加以了解。

一、C o o k i eC o o k i e的含义是“服务器送给浏览器的甜点”,即服务器在响应请求时可以将一些数据以“键-值”对的形式通过响应信息保存在客户端。

当浏览器再次访问相同的应用时,会将原先的C o o k i e通过请求信息带到服务器端。

下面的S e r v l e t展示了C o o k i e的功能。

.........p u b l i c v o i d d o G e t(H t t p S e r v l e t R e q u e s t r e q u e s t,H t t p S e r v l e t R e s p o n s e r e s p o n s e) t h r o w s S e r v l e t E x c e p t i o n,I O E x c e p t i o n{r e s p o n s e.s e t C o n t e n t T y p e("t e x t/h t m l");P r i n t W r i t e r o u t=r e s p o n s e.g e t W r i t e r();S t r i n g o p t i o n=r e q u e s t.g e t P a r a m e t e r("o p t i o n");i f("s h o w".e q u a l s(o p t i o n)){//获得请求信息中的C o o k i e数据C o o k i e[]c o o k i e s=r e q u e s t.g e t C o o k i e s();i f(c o o k i e s!=n u l l){//找出名称(键)为“c o o l”的C o o k i ef o r(i n t i=0;i<c o o k i e s.l e ng t h;i++){i f("c o o l".e q u a l s(c o o k i e s[i].g e t N a m e())){o u t.p r i n t l n("<h2>"+c o o k i e s[i].g e t N a m e()+":"+c o o k i e s[i].g e t V a l u e()+"</h2>");}}}}e l s e i f("a d d".e q u a l s(o p t i o n)){//创建C o o k i e对象C o o k i e c o o k i e=n e w C o o k i e("c o o l","y e a h!");//设置生命周期以秒为单位c o o k i e.s e t M a x A g e(20);//添加C o o k i er e s p o n s e.a d d C o o k i e(c o o k i e);}.........该S e r v l e t对应的u r l-p a t t e r n为/t e s t C o o k i e当浏览器请求地址“.../t s t/t e s t C o o k i e?o p t i o n=a d d”时,该S e r v l e t创建一个C o o k i e 对象,存储的键-值对为“c o o l”-“y e a h”。

通过r e s p o n s e的a d d C o o k i e方法将该C o o k i e 信息添加到相应信息中。

需要注意的是c o o k i e的s e t M a x A g e方法用于设置该c o o k i e生命周期,单位是秒,如果过了这个期间,C o o k i e将失效。

s e t M a x A g e方法的参数如果为负值则表示该C o o k i e将在浏览器关闭时过期,如果参数为0则表示立刻删除该C o o k i e。

访问该地址,对应的请求和响应的H T T P信息为:请求:G E T/t s t/t e s t C o o k i e?o p t i o n=a d d H T T P/1.1A c c e p t:i m a g e/g i f,i m a g e/x-x b i t m a p,i m a g e/j p e g,i m a g e/p j p e g,a p p l i c a t i o n/x-s h o c k w a v e-f l a s h,a p p l i c a t i o n/x-s i l v e r l i g h t,**A c c e p t-L a n g u a g e:z h-c nU A-C P U:x86A c c e p t-E n c o d i n g:g z i p,d e f l a t eU s e r-A g e n t:M o z i l l a/4.0(c o m p a t i b l e;M S I E7.0;W i n d o w s N T5.1)H o s t:192.168.5.100:8080C o n n e c t i o n:K e e p-A l i v eC o o k i e:c o o l=y e a h!响应:H T T P/1.1200O KS e r v e r:A p a c h e-C o y o t e/1.1C o n t e n t-T y p e:t e x t/h t m l;c h a r s e t=I S O-8859-1C o n t e n t-L e n g t h:21D a t e:S u n,29J u n200806:15:26G M T<h2>c o o l:y e a h!</h2>注意,请求协议头中用于携带c o o k i e信息的格式。

C o o k i e可以用于保持用户的会话状态,但C o o k i e信息保存在客户端,存在较大的安全隐患,且一般浏览器对C o o k i e的数目及数据大小有严格的限制。

在W e b应用中,一般情况下通过H t t p S e s s i o n对象保持会话状态。

二、S e s s i o nS e s s i o n对象的原理在于,服务器可以为客户端创建并维护一个所谓的S e s s i o n对象,用于存放数据。

在创建S e s s i o n对象的同时,服务器将会为该S e s s i o n对象产生一个唯一编号,这个编号称之为S e s s i o n I D,服务器以C o o k i e的方式将S e s s i o n I D存放在客户端。

当浏览器再次访问该服务器时,会将S e s s i o n I D作为C o o k i e信息带到服务器,服务器可以通过该S e s s i o n I D检索到以前的S e s s i o n对象,并对其进行访问。

需要注意的是,此时的C o o k i e 中仅仅保存了一个S e s s i o n I D,而相对较多的会话数据保存在服务器端对应的S e s s i o n对象中,由服务器来统一维护,这样一定程度保证了会话数据安全性,但增加了服务器端的内存开销。

存放在客户端的用于保存S e s s i o n I D的C o o k i e会在浏览器关闭时清除。

我们把用户打开一个浏览器访问某个应用开始,到关闭浏览器为止交互过程称为一个“会话”。

在一个“会话”过程中,可能会向同一个应用发出了多次请求,这些请求将共享一个S e s s i o n对象,因为这些请求携带了相同的S e s s i o n I D信息。

1.S e s s i o n工作原理下面的S e r v l e t用来演示S e s s i o n的工作原理:.........p u b l i c v o i d d o G e t(H t t p S e r v l e t R e q u e s t r e q u e s t,H t t p S e r v l e t R e s p o n s e r e s p o n s e) t h r o w s S e r v l e t E x c e p t i o n,I O E x c e p t i o n{r e s p o n s e.s e t C o n t e n t T y p e("t e x t/h t m l");P r i n t W r i t e r o u t=r e s p o n s e.g e t W r i t e r();S t r i n g o p t i o n=r e q u e s t.g e t P a r a m e t e r("o p t i o n");i f("c r e a t e".e q u a l s(o p t i o n)){//获得H t t p S e s s i o n对象H t t p S e s s i o n s e s s i o n=r e q u e s t.g e t S e s s i o n();//设置S e s s i o n对象的最长不活动间隔s e s s i o n.s e t M a x I n a c t i v e I n t e r v a l(30);//获取S e s s i o n中的数据L i s t l i s t=(L i s t)s e s s i o n.g e t A t t r i b u t e("l i s t");i f(l i s t==n u l l){l i s t=n e w A r r a y L i s t();l i s t.a d d("h e y");//向S e s s i o n中添加数据s e s s i o n.s e t A t t r i b u t e("l i s t",l i s t);}e l s e{l i s t.a d d("h e y");}o u t.p r i n t l n(l i s t);}e l s e i f("i n v a l i d a t e".e q u a l s(o p t i o n)){H t t p S e s s i o n s e s s i o n=r e q u e s t.g e t S e s s i o n(f a l s e);i f(s e s s i o n!=n u l l){//使S e s s i o n对象失效s e s s i o n.i n v a l i d a t e();}}.........该S e r v l e t的u r l-p a t t e r n为/t e s t S e s s i o n。

相关主题