Session&Cookie
1. 会话
1.1 什么是会话
每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。
例如:用户点击超链接通过一个servlet购买了一个商品,程序应该想办法保存用户购买的商品,以便于用户点结帐servlet时,结帐servlet可以得到用户购买的商品为用户结帐。
通过回话,能够实现浏览器与服务器交互时的部分数据存取。
会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
1.2 为什么需要会话
因为HTTP协议是无状态的。
这说明HTTP不能记录任何信息,但是交互需要承前启后,因此引入“会话技术”。
详情可以查看百度百科:HTTP无状态协议
1.3 会话技术
会话技术有两种:
- Cookie:客户端(浏览器)技术
- 程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
- Session:服务端技术
- 服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务
2. Cookie
- 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
- 一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
- 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
- 如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
2.1 API
javax.servlet.http.Cookie
- javax.servlet.http.Cookie类用于创建一个Cookie
- response接口中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。
- request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。
2.1.1 Cookie的流程
- 1.服务端定义addCookie,在响应头中增加set-Cookie,客户端接收
- 2.客户端创建cookie
- 3.客户端再次访问的时候,将上次的cookie返回给服务器
2.1.2 Cookie类的方法
- public Cookie(String name,String value)
- setValue与getValue方法
- setMaxAge与getMaxAge方法 (秒) 生命周期
- setPath与getPath方法
- setDomain与getDomain方法
- getName方法
2.1.3 Cookie类的常用属性
2.2 Cookie应用场景
2.2.1 记录访问时间
先检验是否存在Cookie,若有,则获取Cookie中的数据,若无,则创建Cookie,以供下次使用
2.2.1.1 maxAge方法
顾名思义,最大年龄–>Cookie的存活时间
maxAge:
cookie的缓存时间。默认是-1,默认存在浏览器的缓存中。单位是秒
- 负数:表示cookie的数据存在浏览器缓存中(关闭浏览器删除)
- 0:表示删除cookie(得响应给浏览器,他才会删除,response.addCookie())
- 正数:缓存在持久化磁盘上的时间
2.2.2. 记录用户名
2.2.2.1 html(jsp)
2.2.2.2 js
//通过document对象获取cookie,拿到用户名以及是否remember。
//通过window.onload在页面加载时根据remember的值选择是否载入用户名
<script type="text/javascript">
var cookies = document.cookie.split(';');
//通过key获取cookie的值
function getCK(mkey) {
for(var i = 0;i<cookies.length;i++){
var kv = cookies[i].split('=');
//key有可能空字符串
if( kv[0].trim() == mkey){
return kv[1].trim();
}
}
return '';
}
window.onload = function(){
var remember = getCK('remember');
var username = getCK('username');
console.log(remember + "---");
console.log(username);
if(remember == 'true'){//记住密码
//console.log('记住密码');
var userNameInput = document.getElementById('username');
userNameInput.value = username;
var rememberInput = document.getElementById('remember');
rememberInput. checked="checked";
}
}
</script>
2.2.2.3 Servlet
2.2.3 历史记录
目标:
查看书籍的浏览记录
2.2.3.1 原理
- 1.客户端访问书籍(查看一本具体的书,viewBookServlet处理)(发送响应给服务端),服务端返回时让其设置Cookies
- 2.客户端查看书籍首页(查看所有的书,showAllBookServlet处理),服务端拿到cookies,放在集合中,然后根据cookies(访问记录)响应历史内容给客户端
2.2.3.2 model
2.2.3.3 模仿数据库数据
2.2.3.4 showAllBookServlet
注:此处通过getWriter().writer()直接写回html代码,这种方式仅用于测试学习,不适合正式开发
这个Servlet用于展示所有的书籍,并获取cookie展示历史记录(不做cookie的创建)
2.2.3.5 viewBookServlet
用户查看书籍详情页
为其创建cookie,作为访问历史的记录
为保证历史记录的正确性,每次都需要移除旧的相同cookie,创建新的cookie并更新存活时间。
3. Session
在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象)
注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
Session特点:
- Session是一种key-value的键值对
- Session对象是在客户端第一次请求服务器的时候自动创建的。(不需要我们来创建session,我们需要做的就是set和get数据,但是,访问静态资源是不会创建session的)
- Session技术把用户的数据写到用户独占的session中。
- Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。
- 每个浏览器存储自己的数据到Session中,服务器一般把Session放在内存里
- Session的数据是不能被其它浏览器共享的,是相对安全的
- Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session
疑问:服务器是如何实现一个session为一个用户浏览器服务的?
- 服务器会为每个浏览器分配一个session ID,然后把Session ID通过Cookie的形式存储在客户端
- 客户端第一次访问服务端的时候,服务端创建session,分配id并通过cookies响应给客户端
- 客户端将带session的cookies存在本地,下次访问的时候,会带上cookies
- 注意:尽管session保存在cookie中,当浏览器关闭后,cookie还在,但session在服务端已经销毁,因此相当于没有保存session
所以:创建session,也会同时创建cookie
3.1 session常用方法
- 把数据保存在HttpSession对象中,该对象也是一个域对象。
- void setAttribute(String name,Object value);
- Object getAttribute(String name);
- void removeAttribute(String name);
- HttpSession.getId()
- setMaxInactiveInterval(int interval) 设置session的存活时间
- invalidate() 使此会话无效,删除session
HttpSession request.getSession(boolean create)
参数create:
true:根据客户端JSESSIONID的cookie的值,找对应的HttpSession对象,找不到则创建一个
false:根据客户端JSESSIONID的cookie的值,找对应的HttpSession对象,找不到返回null(不会创建新的,只是查询)。
3.2 session状态
- 创建:当浏览器第一次访问服务器动态资源就创建
- 活着:服务器应用运行时
- 死亡:
- Session.invalidate();强制销毁
- 超时:默认30分钟
- setMaxInactiveInterval(int )单位秒
可以在xml统一配置存活时间
<session-config>
<!--单位是分钟-->
<session-timeout>1</session-timeout>
</session-config>
3.3 session 实验
考虑“会话”以及“一个浏览器拥有一个session对象”的含义,尽管上面是两个不同的访问,但能够共享同一个session。
3.4 session应用场景
3.4.1 购物车实现
原理:利用session,保存用户的临时操作数据
- 展示所有书
- 加入购物车:用户点击购买书之后,将该书加入session
- 查看购物车:从session中获取数据
- 购物列表showAllBookServlet,展示所有书
- 购买servlet
- 显示购物车
3.4.2 验证码
原理:
1.在验证码创建的地方,将验证码存到session
2.在用户输入验证码的地方,访问服务器后将用户输入与session中的验证码进行对比
实现前先思考:用session进行验证码和用request对验证码进行验证的区别?(本节底部给出解释)
- 生成验证码,存入session
- 登录页面
这种写法仅用于测试,一般来说使用form的POST方法提交登录数据。
- 登录处理servlet
用session进行验证码和用request对验证码进行验证的区别?
- session:
生成验证码并保存、传递验证码、检验验证码,都是通过一个session会话实现的,好处显而易见,保证了数据的安全,实现方法简洁优雅。- request:
生成验证码后保存到服务端、通过response传递验证码给浏览器、浏览器通过request传回服务端、服务端进行验证码比对。显然,上述方法麻烦多了,而且数据不安全,甚至可能不稳定。
3.5 session持久化
xx持久化:将xx保存在本地硬盘(或者数据库),一般指的就是数据的持久化。session也是数据。
- 持久化的优点:
- 节约内存空间
- 确保在服务器重启或单个Web应用重启后,能恢复重启前的会话;
3.5.1 持久化状态
Session在其生命周期中,可能会在运行时状态和持久化状态之间转换。(被持久化对象需要先实现可序列化接口 Serializable)
Serializable:凡是想要将对象保存在本地,都需要实现可序列化接口。
3.5.1.1 搁置
会话从运行时状态变为持久化状态的过程称为 —— 搁置(从内存到硬盘);
在以下情况下,Session会被搁置:
- 当服务器重启或单个Web应用终止时,Web应用中的Session会被搁置;
- 会话处于不活动状态的时间太长,达到了特定的限定值;
- Web应用中处于运行状态的会话数目太多,达到了特定的限制值,部分Session被搁置
3.5.1.2 激活
会话从持久化状态变为运行时状态的过程称为激活;
在以下情况下,Session会被激活:
- 当服务器重启或单个Web应用重启时,Web应用中的Session会被激活
- 处于Session中的客户端想Web应用发出HTTP请求,相应的Session会被激活
3.5.2 持久化路径
会话持久化的路径是在**\work\Catalina\localhost\项目名**下
4. cookie与session的区别与联系
区别
- cookie:
- 服务器通知浏览器创建,浏览器保存。
- 保存时间由浏览器决定,通常非常长。
- 不考虑数据安全,可使用cookie
- 考虑服务器性能,使用cookie
- session:
- 服务器创建,服务器保存,通过cookie将session传递给浏览器。
- 有效时间由服务器决定,通常只有一个会话时长。
- 考虑数据安全,使用session
- 不考虑服务器性能,使用session
联系
- session是通过cookie来工作的
session和cookie之间是通过$_COOKIE[‘PHPSESSID’]来联系的,通过$_COOKIE[‘PHPSESSID’]可以知道session的id,从而获取到其他的信息。
cookie和session结合使用
- 存储在服务端:通过cookie存储一个session_id,具体的数据则是保存在session中。如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做server side session。
- 将session数据加密,然后存储在cookie中。这种专业术语叫做client side session。