概述
由于HTTP的无状态性,使得会话管理或会话跟踪成为Web应用开发一个无可避免的主题。默认下,一个Web服务器无法区分一个HTTP请求是否为第一次访问。
例如,一个Web邮件应用要求用户登录后才能查看邮件,因此,当用户输入了相应的用户名和密码后,应用不应该再次提示需要用户登录,应用必须记住哪些用户已经登录。换句话说,应用必须能管理用户的会话。
本文阐述4种不同的状态保持技术:URL重写、隐藏域、cookies和HTTPSession对象。
会话机制是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookies和Session。
Cookies通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
什么是会话
会话是指在一段时间内,用户使用同一个浏览器进程与Web应用程序之间的交互过程。
会话通常用来跟踪用户的状态,缓存用户在此浏览器进程中的信息。
当用户关闭浏览器时,上一个Session也就无法再次获得了(Cookie的maxAge为-1的情况)。再次打开新的浏览器,将开始一个新的会话。
类javax.servlet.http.HttpSession,每一个HttpSession代表用户的一个会话,每个Session的过期时间默认30分钟。
会话类比
一次会话指的是:就好比打电话,A给B打电话,接通之后,会话开始,直到挂断电话,该次会话就结束了。而浏览器访问服务器,就跟打电话一样,浏览器A给服务器B发送请求,访问Web程序,该次会话就已经接通,其中不管浏览器发送多少请求(就相当于接通电话后说话一样),都视为一次会话,直到浏览器关闭,本次会话结束。其中注意,一个浏览器相当于一部电话,如果使用火狐浏览器,访问服务器,就是一次会话;然后打开goole浏览器,访问服务器,这是另一个会话,虽然是在同一台电脑,同一个用户在访问,但是这是两次不同的会话。
URL重写
URL重写是一种会话跟踪技术,它将一个或多个token添加到URL的查询字符串中,每个token通常为key=value形式,如下:
url?key-1=value-1&key-2=value-2 … &key-n=value-n
注意,URL和tokens间用(?)分割,token间用与号(&)。
URL重写适合于tokens无需太多URL间传递的情况下,然而它有如下限制:
- URL在某些浏览器上最大长度为2000字符;
- 若要传递到下一个资源,需要将值插入到链接中,换句话说,静态页面(无需要通过servlet就可以访问的页面,页面存在即可浏览器直接打开的页面)很难传值;
- URL重写需要在服务端上完成,所有的链接都必须带值,因此当一个页面存在很多链接时,处理过程会是一个不小的挑战;
- 某些字符,例如空格、&、?等必须用base64编码;
- 所有的信息都是可见的,某些情况下不合适。
因为存在如上限制,URL重写仅适合于信息仅在少量页面间传递,且信息本身不敏感。
示例
比如显示最受游客青睐的10个伦敦和巴黎的景点,信息分两页展示,第一页展示指定城市的5个景点,第二页展示另外5个。
实现Top10Servlet类,扩展HttpServlet;使用URL重写来记录所选择的城市和页面,并通过/top10访问。
用户一开始访问该servlet时不带任何请求参数,后端返回一个连接给浏览器,每个链接都包含 token:city=cityName。
网页源码如下:
Please select a city:<br/>
<a href='?city=london'>London</a><br/>
<a href='?city=paris'>Paris</a>
请注意a元素中的href属性,该属性值包括一个问号加token city=london或city=paris。注意,此处为相对URL,即URL中没有协议部分,相对于当前页面。因此,若你点击了任一条链接,则会提交:
http://localhost:8080/app02a/top10?city=london
或
http://localhost:8080/app02a/top10?city=paris
到服务器上。
隐藏域
使用隐藏域来保持状态类似于URL重写技术,但不是将值附加到URL上,而是放到HTML表单的隐藏域中(就是隐藏字段,不在页面显示而已,会将隐藏字段带到后端)。当表达提交时,隐藏域的值也同时提交到服务器端。隐藏域技术仅当网页有表单时有效。
该技术相对于URL重写的优势在于:没有字符数限制,同时无须额外的编码。但该技术同URL重写一样,不适合跨越多个界面。
该技术使用的比较多,比如编辑人员,通常会把人员Id通过表单的方式传到后端。
要强调的是,表单时通过POST方式提交的,因此调用的是servlet的doPost方法。
类似Cookies和Session场景举例
下面举一个形象的例子,顾客去咖啡店和咖啡。顾客类比为浏览器,咖啡店员类比HTTP协议,咖啡店类比Web服务器。
假如一个咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来记录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
A、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道改怎么对待了。这种作为就是协议本身支持状态。但是http协议本身是无状态的。
B、发给顾客一张卡片,上面记录这消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费联系起来。这种做法就是在客户端保持状态。也就是Cookie。顾客就相当于浏览器。
C、发给顾客一张会员卡,除了卡号之外什么信息也不记录,每次消费时,如果顾客出示该卡片,则店员在咖啡店的记录里面找到这个卡号对应的记录添加一些消费信息。这种做法就是在服务器端保持状态。
Cookies
为什么使用Cookies
URL重写和隐藏域仅适合保存无须跨越太多页面的信息。如果需要在多个页面间传递信息,则以上两种技术实现成本高昂,因为你不得不在每个页面都进行相应处理。幸运的是,Cookies技术可以帮助我们。
比如当用户来到微博登陆页面,输入用户名和密码之后点击“登录”后浏览器将认证信息POST给远端的服务器,服务器执行验证逻辑,如果验证通过,则浏览器会跳转到登录用户的微博首页,在登录成功后,服务器如何验证我们对其他受限制页面的访问呢?因为HTTP协议是无状态的,所以很显然服务器不可能知道我们已经在上一次的HTTP请求中通过了验证。当然,最简单的解决方案就是所有的请求里面都带上用户名和密码(URL重写),这样虽然可行,但大大加重了服务器的负担(对于每个request都需要到数据库验证),也大大降低了用户体验(每个页面都需要重新输入用户名密码,每个页面都带有登录表单)。既然直接在请求中带上用户名与密码不可行,那么就只有在服务器或客户端保存一些类似的可以代表身份的信息了,所以就有了cookie与session,cookie和session用来跟踪用户的整个会话。
Cookies介绍
cookies机制采用的是在客户端保持状态的方案。
会话机制的深入理解:
在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或者用户C的购物车内,这不属于同一个会话。
而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一致机制。Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。
借着上面的顾客喝咖啡场景,我们使用B方案,类似于Cookie机制。
Cookie的创建
如何分发会员卡;会员卡的内容:也就是cookie时如何创建的?创建后如何发送给客户端?
答案是:有服务器进行创建。也就相当于咖啡店来创建会员卡,在创建会员卡的同时,就会将会员卡中的内容也给设置了。
//服务器创建Cookie(以键值对的方式存放内容)
Cookie cookie = new Cookie(key,value);
//服务器将创建好的cookie发送给浏览器端
response.addCookie(cookie);
// 注意:一旦cookie创建好了,就不能在往其中增加别的键值对,但是可以修改其中的内容:
//将key对应的value值修改
cookie.setValue();
Cookie工作原理
客户如何使用会员卡,cookie在客户端如何工作的,工作原理是什么?
这个过程就相当于,咖啡店创建好了会员卡,并且已经设置了其中的内容,交到客户手中,下次客户过来时,就带着会员卡过来,就知道你是会员了,然后咖啡店就拿到你的会员卡对其进行操作。
Cookie的有效期
会员卡的有效期,也就是cookie也是拥有有效期的。这个可以自由设置,默认是关闭浏览器,cookie就没用了。
// 设置cookie被浏览器保存的时间。
cookie.setMaxAge(expiry);
expiry:单位秒,默认-1。
A、expiry=-1:代表浏览器关闭后,也就是会话结束后,cookie就失效了,也就没有了;
B、expiry>0: 代表浏览器关闭后,cookie不会失效,仍然存在。并且会将cookie保存到硬盘中,直到设置时间过期才会被浏览器自动删除;
C、expiry=0: 删除cookie。不管是之前的expiry=-1还是expiry>0,当设置expiry=0时,cookie都会被浏览器给删除。
cookie是有时间限制的,根据生命期不同分成两种:会话cookie和持久cookie;
- 会话Cookie
如果不设置过期时间,则表示这个cookie生命周期为从创建到浏览器关闭为止,只有关闭浏览器窗口,cookie就消失了。这种生命周期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不保存在磁盘上而是保存再内存里。- 持久Cookie
如果设置了过期时间(setMaxAge(606024)),浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如开了两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。
设置持久Cookie:
Cookie cookie = new Cookie("user", "suntao");
cookie.setMaxAge(7*24*60*60); // 一星期有效
response.addCookie(cookie);
浏览网站时,你会经常发现网站登录的地方,会有提示,问你是不是要记住自己的登录状态,像这种情况,登录时填写的一些信息会被以文件的方式存放在客户端的硬盘上。
Cookie的不可跨域名性
很多网站都会使用Cookie。例如,Google会向客户端颁发Cookie,Baidu也会向客户端颁发Cookie。那浏览器访问Google会不会也携带上Baidu颁发的Cookie呢?或者Google能不能修改Baidu颁发的Cookie呢?
答案是否定的。Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google之后携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。
Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。
需要注意的是,虽然网站images.google.com与网站www.google.com同属于google,但是域名不一样,二者同样不能互相操作彼此的Cookie。
正因为Cookie是不可跨域名的,域名www.google.com颁发的Cookie不回被提交到域名www.baidu.com去。这是由Cookie的隐私安全机制决定的。隐私安全机制能够禁止网站非法获取其他网站的Cookie。
正常情况下,同一个一级域名下的两个二级域名如www.helloweenvsfei.com和images.helloweenvsfei.com也不能交互使用Cookie,因为二者的域名并不严格相同。如果想所有helloweenvsfei.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数,例如:
Cookie cookie = new Cookie("time","20080808"); // 新建Cookie
cookie.setDomain(".helloweenvsfei.com"); // 设置域名
cookie.setPath("/"); // 设置路径
cookie.setMaxAge(Integer.MAX_VALUE); // 设置有效期
response.addCookie(cookie); // 输出到客户端
读者可以修改本机C:\WINDOWS\system32\drivers\etc下的hosts文件来配置多个临时域名,然后使用setCookie.jsp程序来设置跨域名Cookie验证domain属性。
注意:domain参数必须以点(".")开始。另外,name相同但domain不同的两个Cookie是两个不同的Cookie。如果想要两个域名完全不同的网站共有Cookie,可以生成两个Cookie,domain属性分别为两个域名,输出到客户端。
Cookie的作用范围
可以设置服务端获取cookie的访问路径,而非在服务端的web项目中所有的servlet都能访问该cookie。
domain属性决定运行访问Cookie的域名,而path属性决定运行访问Cookie的路径。
cookie默认路径:当前访问的servlet父路径。
例如:http://localhost:8080/test01/a/b/c/SendCookieServlet
其默认路径为:/test01/a/b/c。也就是说,在该默认路径下的所有Servlet都能够获取到cookie,
所以/test01/a/b/c/MyServlet 这个MyServlet就能获取到cookie。
修改cookie的访问路径
/*
* 在该服务器下,任何项目,任何位置都能获取到cookie,
* 用途:保证在tomcat下所有的web项目可以共享相同的cookie
* 例如:tieba , wenku , beike 多个项目共享数据。例如用户名。
* /
setPath("/");
// 在test01项目下任何位置都能获取到cookie。
setPath("/test01/");
Cookie的安全属性
HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。
下面的代码设置secure属性为true:
Cookie cookie = new Cookie("time", "20080808"); // 新建Cookie
cookie.setSecure(true); // 设置安全属性
response.addCookie(cookie); // 输出到客户端
提示:secure属性不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密、以防泄密。
Cookie的运用案例
记住用户名
登录时,在服务器端获取到用户名,然后创建一个cookie,将用户名存入cookie中,发送回浏览器端,然后浏览器下次在访问登录页面时,先拿到cookie,将cookie中的信息拿出来,看是否保存了该用户名,如果保存了,那么直接用他,如果没有,则自己手写用户名。cookie需要将所有信息都保存在客户端。因此cookie存在着一定的安全隐患,例如本地cookie中保存的用户名和密码被破译,或cookie被其他网站收集。
历史记录
比如购物网站,都会有我们的浏览记录的,实现原理其实也是用cookie技术,每浏览一个商品,就将其存入cookie中,到需要显示浏览记录时,只需要将cookie拿出来遍历即可。
总结Cookie
工作流程
1. 浏览器访问服务器,服务器servlet创建cookie,保存少量数据,发送浏览器。
2. 浏览器获得服务器发送的cookie数据,将自动的保存到浏览器端。
3. 下次访问时,浏览器将自动携带cookie数据发送给服务器。
Cookie操作
1.创建cookie:new Cookie(name,value)
2.发送cookie到浏览器:HttpServletResponse.addCookie(Cookie)
3.servlet接收cookie:HttpServletRequest.getCookies() 浏览器发送的所有cookie
Cookie api
getName() 获得名称,cookie中的key
getValue() 获得值,cookie中的value
setValue(java.lang.String newValue) 设置内容,用于修改key对应的value值。
setMaxAge(int expiry) 设置有效时间【】
setPath(java.lang.String uri) 设置路径【】
setDomain(java.lang.String pattern) 设置域名 , 一般无效,有浏览器自动设置
isHttpOnly() 是否只是http协议使用。只能servlet的通过getCookies()获得,javascript不能获得。
setComment(java.lang.String purpose) //对该cookie进行描述的信息(说明作用),浏览器显示cookie信息时能看到。
setSecure(boolean flag) 是否使用安全传输协议。为true时,只有当是https请求连接时cookie才会发送给服务器端,而http时不会,但是服务端还是可以发送给浏览端的。
注意:cookie不能发送中文,如果要发送中文,就需要进行特别处理。
JDK提供工具,进行编码
URLEncoder:编码
URLDecoder:解码
// 发送cookie
Cookie cookie = new Cookie(URLEncoder.encode("哈哈"),URLEncoder.encode("呵呵"));
response.addCookie(cookie);
// 获得cookie中文内容
URLDecoder.decoder(request.getCookie().getName); //获取key
URLDecoder.decoder(request.getCookie().getValue); //获取value
Session
同样,会员卡的例子的第三种方法,发给顾客一张会员卡,除了卡号之外什么信息也不记录,每次消费时,如果顾客出示该卡片,则店员在店里的记录上找到这个卡号对应的记录添加一些消费信息。这种做法就是在服务端保持状态。这就是session的用法,在服务端来保持状态,保存一些用户信息。
功能作用:服务器用于共享数据技术。在服务端保存Session的方法很多,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,一般会用专门的Session服务器集群,用来保存用户会话,这个时候Session信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放Session。
注意:同一个机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。
Session原理分析
首先浏览器请求服务器访问Web站点时,程序需要为客户端的请求创建一个Session的时候,服务器首先检查这个客户端请求中是否已经包含了一个session标识、称为SESSIONID,如果已经包含了一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用;如果客户端请求不包含seesionId,则服务器为此客户端创建一个session并且生成一个与此session相关联的sessionId,sessionId的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionId将在本次响应中返回给客户端保存,保存这个SessionId的方式就可以是cookie,这样在交互的过程中,浏览器可以自动的按照规则把这个标识发回给服务器,服务器根据这个sessionId就可以找到对应的session,循环上面的流程。
session获取
// 如果没有将创建一个新的,等效getSession(true);
request.getSession();
有些人不理解,为什么是通过request来获取session,可以这样理解,在获取session时,需要检测请求中是否有session标识,所有需要request来获取。
// flag: true 没有将创建; false 没有将返回null
request.getSession(boolean flag);
session属性操作
xxxAttribute(...)
// 用来存放一些信息,然后才能共享信息
setAttrubute(key,value);
getAttribute(key);
session生命周期
Session保存再服务器端。为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。
Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。
常常会有一种误解“只要关闭浏览器,session就消失了”。其实可以想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。对session来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭了,之所以有这种错觉是因为:
大部分seesion机制都使用会话cookie来保存sessionId,而关闭浏览器后这个cookie如果没有配置超时时间就会消失,再次连接服务器时没有携带sessionId导致无法找到原来的session。
如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。
由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。失效时间,一般是30分钟,当距离客户端上一次使用session的时间超过这个失效时间时(Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session),服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。
我们也可以自己来控制session的有效时间:
// 将session对象销毁
session.invalidate()
// 设置有效时间,单位秒
setMaxInactiveInterval(int interval)
在web.xml中配置session的有效时间
<session-config>
<session-timeout>30</session-timeout> // 单位:分钟
<session-config>
所以,讨论了这么久,session的生命周期就是:
创建:第一次调用getSession()
销毁:
1、超时,默认30分钟
2、执行api:session.invalidate()将session对象销毁、setMaxInactiveInterval(int interval) 设置有效时间,单位秒
3、服务器非正常关闭
A、自杀,直接将JVM马上关闭
B、如果正常关闭,session就会被持久化(写入到文件中,因为session默认的超时时间为30分钟,正常关闭后,就会将session持久化,等30分钟后,就会被删除)
位置: D:\java\tomcat\apache-tomcat-7.0.53\work\Catalina\localhost\test01\SESSIONS.ser
session id的URL重写
如果客户端的浏览器禁用了 Cookie 怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
当浏览器将cookie禁用,基于cookie的session将不能正常工作,每次使用**request.getSession()**都将创建一个新的session。达不到session共享数据的目的,但是我们知道原理,只需要将session id 传递给服务器session就可以正常工作的。解决:通过URL将session id 传递给服务器——URL重写。
HttpServletResponse类提供了两种方法实现URL地址重写
- 在链接中直接实现URL地址重写:encodeURL(String url);
<td>
<a href="<%=response.encodeURL("index.jsp?c=1&wd=Java") %>">Homepage</a>
</td>
上面的方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。重写后的输出可能是这样的:
<td>
<ahref="index.jsp;jsessionid=0CCD096E7F8D97B0BE608AFDC3E1931E?c=1&wd=Java">Homepage</a>
</td>
即在文件名的后面,在URL参数的前面添加了字符串“;jsessionid=XXX”。其中XXX为Session的id。分析一下可以知道,增添的jsessionid字符串既不会影响请求的文件名,也不会影响提交的地址栏参数。用户单击这个链接的时候会把Session的id通过URL提交到服务器上,服务器通过解析URL地址获得Session的id。
- 如果页面重定向(Redirection),URL地址重写:encodeRedirectURL(String url);
<%
if(“administrator”.equals(userName)) {
response.sendRedirect(response.encodeRedirectURL(“administrator.jsp”));
return;
}
%>
效果跟response.encodeURL(String url)是一样的:如果客户端支持Cookie,生成原URL地址,如果不支持Cookie,传回重写后的带有jsessionid字符串的地址。(注:由于大部分的手机浏览器都不支持Cookie,WAP程序都会采用URL地址重写来跟踪用户会话)。
Session中禁止使用Cookie
既然WAP上大部分的客户浏览器都不支持Cookie,那么索性禁止Session使用Cookie,统一使用URL地址重写会更好一些。Java Web规范支持通过配置的方式禁用Cookie。下面举例说一下怎样通过配置禁止使用Cookie。
- 打开项目sessionWeb的WebRoot目录下的META-INF文件夹(跟WEB-INF文件夹同级,如果没有则创建),打开context.xml(如果没有则创建),编辑内容如下:
/META-INF/context.xml
<?xml version='1.0' encoding='UTF-8'?>
<Context path="/sessionWeb"cookies="false">
</Context>
- 或者修改Tomcat全局的conf/context.xml,修改内容如下:
context.xml
<!-- The contents of this file will be loaded for eachweb application -->
<Context cookies="false">
<!-- ... 中间代码略 -->
</Context>
部署后TOMCAT便不会自动生成名JSESSIONID的Cookie,Session也不会以Cookie为识别标志,而仅仅以重写后的URL地址为识别标志了。
注意:该配置只是禁止Session使用Cookie作为识别标志,并不能阻止其他的Cookie读写。也就是说服务器不会自动维护名为JSESSIONID的Cookie了,但是程序中仍然可以读写其他的Cookie。
Session常用方法
1、void setAttribute(String attribute, Object value) 设置Session属性。(value参数可以为任何Java Object。通常为Java Bean。value信息不宜过大)
2、String getAttribute(String attribute) 返回Session属性
3、Enumeration getAttributeNames() 返回Session中存在的属性名
4、void removeAttribute(String attribute) 移除Session属性
5、String getId() 返回Session的ID。该ID由服务器自动创建,不会重复
6、long getCreationTime() 返回Session的创建日期。
7、long getLastAccessedTime() 返回Session的最后活跃时间。返回类型为long。
8、int getMaxInactiveInterval() 返回Session的超时时间。(单位为秒。超过该时间没有访问,服务器认为该Session失效)
9、void setMaxInactiveInterval(int second) 设置Session的超时时间。单位为秒
10、boolean isNew() 返回该Session是否是新创建的
11、void invalidate() 使该Session失效
总结
- 知道什么是cookie和什么是session?
cookie是一种在客户端记录用户信息的技术,因为Http协议是无状态的,为了解决这个问题而产生了cookie,记录用户名等一些应用。
session是一种在服务端记录用户信息的技术,一般session用来在服务器端共享数据。 - cookie的工作原理?seesion的工作原理?
cookie工作原理,可以看上面讲解cookie的那张图,cookie是由服务器端创建发送回浏览器端的,并且每次请求服务器都会将cookie带过去,以便服务器知道该用户是哪个。其cookie中是使用键值对来存储信息的,并且一个cookie只能存储一个键值对。所以在获取cookie时,会获取所有的cookie,然后从其中遍历。
session的工作原理就是依靠cookie来做支撑,第一次使用request.getSession()时session被创建,并且会为该session创建一个独一无二的sessionid存放到cookie中,然后发送会浏览器端,浏览器端每次请求时,都会带着这个sessionid,服务器就会认识该sessionid,知道了sessionid就找得到哪个session。以此来达到共享数据的目的。这里需要注意的是,session不会随着浏览器的关闭而死亡,而是等待超时时间。 - 说是Cookie和Session的区别?
1、Cookie和Session都是会话技术,Cookie是运行在客户端,Session是运行在服务器端。
2、Cookie有大小限制以及浏览器在存cookie的个数也有限制,Session是没有大小限制和服务器的内存大小有关。
3、Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可以进行攻击。
4、Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力。
为什么需要使用cookie和session,可以看看那个会员卡的例子,cookie和session只是为了解决http协议无状态的这种缺陷,为了记录用户信息,记录浏览器和服务器之间的状态而衍生出来的。