Web程序中常用Session和Cookie技术来进行会话跟踪,Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
我们都知道Http协议是无状态的协议,一旦数据提交完毕,客户端与服务端的连接就会关闭,再次交换数据需要建立新的连接,这就意味着服务器无法从连接上跟踪会话。比如有些网站下载东西需要会员先登陆,单纯的请求响应无法得知顾客是否已经登陆;再比如网上购物,购物车怎么知道顾客挑选过哪些商品呢?这些情况都需要我们跟踪会话,而cookie和session就可以做到。
下面是我看到的最好理解cookie和session的讲述:
一家烤鸭店老板为了促进销售,特发布“每购满10只即可免费赠送一只”的优惠措施。除了家里有什么红白喜事要飨客之外,应该不会有人一次性购买10只烤鸭吧?所以老板得想个法子来记录顾客的消费数量,这里总共有三种方案:
概念理解完了,就来看看cookie和session对象的使用吧!
Cookie常用的获取方法: Cookie[] cookies = request.getCookies(); 添加方法: response.addCookie(CookieDemo);
Cookie常用的属性有 name,value,maxAge,secure,path,domain,comment,version等,JSESSIONID这个Cookie是Tomcat自动生成的。maxAge决定着Cookie的有效期,单位为秒,使用getMaxAge()和setMaxAge()来读写,若为负数,则表示Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie失效。这种cookie成为临时性cookie,不会被持久化,只会保存在浏览器内存中。若为0则表明要删除该Cookie。Cookie持久化是指写到对应的Cookie文件中。但是在提交cookie,浏览器只提交name和value属性。设置domain属性可以是两个二级域名共享Cookie,必须以“ . ” 开始。设置为“/”时允许所有路径使用Cookie。setSecure(true)可以使浏览器在安全协议中传输此类Cookie。Cookie具有不可跨域名性,浏览器不会带着Google的cookie去访问Baidu的网站。
Session对象是在客户端第一次请求服务器时候创建的,也是一种key-value的属性对,通过get/setAttribute()读写状态信息。使用request.getSession()方法获取session,还有种方法getSession(boolean create),区别在于如果Session不存在,前者返回null,后者在true的情况下自己创建。服务器一般把session放在内存中,每个用户对应一个独立的session,只访问静态资源时并不会创建Session,而如果访问有效,每次服务器都会更新session的最后访问时间。
session的常用方法有:setAttrbute(),getAttribute(),removeAttribute(),getMaxInactiveInterval(),invalidate()等,tomcat中session默认的超时时间是 20分钟,可以通过setMaxInactiveInterval()来设置,也可以使用方法invalidate()来说session失效。
服务器向浏览器发送一个名为JSESSIONID的Cookie,来匹配Session的id,判断是否为同一用户。但是如果浏览器禁止了cookie,则需要进行URL地址重写,其原理是将用户的Session的id信息重写到URL地址中,这样即使是浏览器不支持cookie,也可以解析出URL的jsessionid获得session的id,进行判断。使用方法是response.encodeURL(),response.encodeRedirectURL().还有一种方法是表单隐藏字段技术,就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。
下面比较一下Session和Cookie:
首先原理和具体用途不怎么一样,Cookie可用来显示上次访问时间,访问次数,浏览历史记录等,而session可用来完成用户登录,防止表单重复提交,一次性验证码等。
存取方式:cookie只能保存ASCII字符串,若要存Unicode字符或二进制数据,需要进行UTF-8、GBK、BASE64等编码,且不可存复杂信息,而Session可以存任何类型的数据,包括而不限于String、List、Map等,JavaBean类、对象都可以。
隐私安全:Cookie存在浏览器中,对客户端可见,而Session存在服务器上,对客户透明。但使用cookie,可以将cookie加密在传输给客户端。
有效期:只要设置cookie的maxAge为很大很大的数字或者Integer.MAX_VALUE就会得到长期有效,而Session理论上可以,但是其依赖JSESSIONID的Cookie,况且如果服务器存放了太多了Session,会容易溢出。
服务器压力:cookie不存在此问题,Session会在并发用户很多时,造成负担。
此外,浏览器可以禁止cookie,而Session不支持跨域名访问。