Java中Cookie和Session的那些事儿
cookie和session都是为了保持用户的访问状态,一方面为了方便业务实现,另一方面为了简化服务端的程序设计,提高访问性能。cookie是客户端(也就是浏览器端)的技术,设置了cookie之后,每次访问服务端,请求中都会带上cookie;session是服务端技术,在服务端存储用户的访问信息。
使用cookie传递信息,随着cookie个数增多和访问量增大,它占用的带宽会越来越大;使用session保存信息,最大的弱点就是不容易在多台服务器之间共享。
1 cookie
通俗地讲,当用户使用http访问服务器时,服务器会将一些键值对信息返回给客户端浏览器,并且给这些数据加一些限制条件,在符合限制条件情况下用户下次访问服务器时,会带上之前设置的cookie键值对信息。当该用户输入 url 时,浏览器便会在本地硬盘上查找与该 url 关联的 cookie。如果该 cookie 存在,浏览器便将该 cookie 与页请求一起发送到您的站点。
cookie 与网站关联,而不是与特定的页面关联。因此,无论用户请求站点中的哪一个页面,浏览器和服务器都将交换 cookie 信息。用户访问不同站点时,各个站点都可能会向用户的浏览器发送一个 cookie;浏览器会分别存储所有 cookie。
cookie属性项
当前cookie有2个版本,version 0 和 version 1,它们有2种设置响应头标识,分别是"set-cookie"和"set-cookie2"。
cookie 0属性值
cookie 1属性值
java中使用cookie示例
@override public void doget(httpservletrequest request, httpservletresponse response) throws ioexception { response.setcontenttype("text/html;charset=utf-8"); printwriter out = response.getwriter(); cookie[] cookies = request.getcookies(); string name = getcoodie(cookies, "name"); if (name == null) { response.addcookie(new cookie("name", "luoxn28")); } else { system.out.println(name); } out.println("hello world"); } public static string getcoodie(cookie[] cookies, string key) { if (cookies != null) { for (cookie cookie : cookies) { if (cookie.getname().equals(key)) { return cookie.getvalue(); } } } return null; }
使用cookie的一些注意事项(以java使用为例)
•所创建的cookie的name和value不能为非assic字符,如果是中文,可以通过rrlencoder将其编码,否则会抛出java.lang.illegalargumentexception异常。
•多出现多个name和value值时,它们实在同一个"cookie"头中的。
•cookies的值中可以保存除了“;”以外的标点符号。但是不能保存汉字。保存汉字会出现乱码。
cookie的一些限制
cookie是http头中的一个字段,http本身对该字段没有限制,但是cookie最终存储在浏览器中,不同的浏览器对cookie的存储有一些限制,如下表所示:
如果试图存储更多 cookie,则最旧的 cookie 便会被丢弃。
2 session
session解决了cookie增多时会增加客户端与服务器的数据传输量问题,同一个客户端与服务器交互时,不需要每次都传回所有的cookie值,而是只要传回一个id值,这个id是客户端第一次访问服务器时生成的,而且每个客户端是唯一的,这个id通常是name为jsessionid的一个cookie。
session是如何基于cookie工作的呢,可以是基于url path parameter方式;也可以是基于cookie,如果没有修改context容器中的cookies标识,则默认也是支持的。当浏览器不支持cookie功能时,浏览器会将用户的sessioncookiename重写到用户请求的url参数中,它的传递方式如/path/servlet;name=xxx;name2=xxx2?name3=xxx3。sessioncookiename如果在web.xml中配置session-config配置项,其cookie-config下的name属性就是这个sessioncookiename的值。如果没有配置session-config配置项,默认的sessioncookienamejiushi “jsessionid”。注意,与session关联的cookie与其他cookie并没有什么不同。如果客户端也支持cookie,则tomcat仍会解析cookie中的session id,并会覆盖url中的session id。
session如何工作
有了session id,服务器就可以创建httpsession对象了,第一次调用request.getsession()方法,如果没有对应的httpsession对象,则会创建一个新的,并将这个对象加入到org.apache.catalina.manager的sessions容器中保存。manage保存所有的session生命周期,session过期被回收,服务器关闭,session被序列化到磁盘。注意,一个客户端对应一个session对象,这个对象正是保存我们创建的session值的。
request.getsession()方法调用的standardsession永远都会存在,即使与这个客户端关联的session已经过期。如果过期,则会创建一个新的,但是以前设置的session值将会丢失。
3 cookie与session安全性比较
cookie将保存的数据通过http头部从客户端传到服务端,从服务端再传回到客户端,所有的数据都保存在客户端浏览器中,这些数据都是可以访问到的,甚至可以通过插件添加、修改cookie,所有cookie的安全性是比较差的。相比较而言,session将数据保存在服务器端,安全性高很多,只需要cookie传回一个cookie id就可以,所以session更适合保存用户隐私和重要的数据。
分布式session框架
在大型互联网应用中,单用cookie和session都是不可行的,因为如果使用cookie可以很好地解决应用的分布式部署问题,大型互联网应用系统一个应用有上百台机器,而且有很多不同的应用系统协同工作,由于cookie是将数据存储在用户浏览器中,用户每次访问都会讲数据带回到服务器,也就解决了同一个用户的请求在不同服务器上处理而导致的cookie不一致问题。
由于应用是一个集群,所以不能将session都保存在每台服务器的内存中,如果每台服务器有几十万访问用户,服务器内存也容不下,即使容得下,也无法保证该session同步到其他服务器中,所以共享这些session需要将它们保存在专门的分布式缓存中,可以随时读取和写入,性能要够好满足要求,如memcache/redis或者淘宝的开源分布式框架tair都是很好的选择。
表单重复提交问题
网站中有很多地方有重复提交表单问题,为了防止表单重复提交,就要标识用户的每一次访问请求,使得每一次访问请求对服务端来说都是唯一的,为了标识用户的每次请求,可以在用户请求的表单域增加一个隐藏表单项,其值为唯一的token,如:
<form id="form" method="post"> ... <input type=hidden name="token" value="xxx"/> </form>
用户请求表单时生成唯一的token,并且设置到该用户的session中,等用户提交时检测这个token是否和session中保存的token一致,如果一致,说明没有重复提交,同时把session中的token更新成一个新的token值;否则用户提交上来的token已经不是当前请求的合法token,提交失败。
以上所述是小编给大家介绍的java中cookie和session的那些事儿,希望对大家有所帮助