1. 会话概述
-
会话是指一个客户端与Web服务器之间连续发生一系列请求和响应过程
-
例如:用户甲和乙分别登录了购物网站,甲购买了一个手机,乙购买了一个iPad,当这两个用户结账时Web服务器需要对甲和乙的信息分别进行保存
-
会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
2. Cookie对象
2.1 什么是Cookie
-
Cookie:客户端会话跟踪技术,可以将会话过程中的数据保存到用户的浏览器中,以后每次请求都携带Cookie数据进行访问,从而使浏览器何服务器可以更好地进行数据交互
-
服务器向客户端发送Cookie时,绘制响应头字段中增加Set-Cookie响应头字段
Set-Cookie:uesr=why; Path=/; //user表示Cookie的名称,why表示cookie的值,Path表示cookie的属性
-
传输过程
- 当用户第一次访问服务器时,服务器会在响应消息中增加set-Cookie头字段,将用户信息以Cookie形式发送给浏览器
- 用户浏览器一旦接收了服务器发送的Cookie信息,就会将它保存中自身的缓冲区中
- 当浏览器后续访问该服务器时,都会在请求消息中将用户信息以Cookie的形式发送给服务器,从而使服务器分辨出当前请求是由哪个用户发出的
2.2 Cookie API
-
构造方法:
/* name指定cookie的名称,value指定cookie的值 注意:cookie一旦创建,它的名称就不可以再更改,它的值可以为任何值,创建后允许被更改 */ public Cookie(String name, String value)
-
常用方法
//返回cookie的值 String getValue(); /* 设置cookie在浏览器客户机上保存有效的秒数 1. 如果设置为正整数,则会将cookie信息保存在本地硬盘中,从当前时间开始,在没有超过指定时间之前,cookie保持有效,并 且同一台计算机上运行的该浏览器都可以使用这个cookie的信息 2. 负整数(默认值),则将cookie信息保存到浏览器的缓存中,当浏览器关闭时,cookie会被删除 3. 0,浏览器会立即删除这个cookie信息 */ void setMaxAge(int expiry); //返回cookie在浏览器上保持有效的秒数 int getMaxAge(); /* 设置该cookie项的有效目录路径 如果没有设置Path属性,那么该cookie只对当前访问路径所属的目录及其子目录有效 如果想让cookie对站点的所有目录小的访问路径都有效,应将其Path属性设置为"/" */ void setPath(String uri); //返回该cookie项的有效目录路径 String getPath(); /* 设置该cookie的有效域 domain属性用于指定浏览器访问的域,例如:百度的域为"baidu.com" 设置domain属性时,其值必须以"."开头,如domain=.baidu.com 在默认情况下,domain属性的值为当前主机名,浏览器在访问当前主机下的资源时,都会将cookie信息发送给服务器(当前主机) 注意:domain属性的值不区分大小写 */ void setDomain(String pattern); //返回该cookie的有效域 String getDomain(); //设置该cookie采用的协议版本 void setVersion(int V); //返回该cookie项采用的版本协议 void getVersion(); //设置该cookie项的注解部分 void setComment(String purpose); //返回该cookie项的注解部分 String getComment(); //设置该cookie项是否只能使用安全的协议传送 void setSecure(boolean flag); //返回该cookie项是否只能使用安全的协议传送 boolean getSecure();
-
查看响应头中的数据
-
查看请求头中的信息
2.3 Cookie存储中文
- Cookie不能直接存储中文,所以需要使用URL进行编码何解码
String value = "吴";
//对中文进行URL编码
value = URLEncoder.encode(value, "UTF-8");
//获取的是URL编码后的值 %E5%BC%A0%E4%B8%89
String value = cookie.getValue();
//URL解码
value = URLDecoder.decode(value, "UTF-8");
3. Session对象
3.1 什么是Session
- Session:服务端会话跟踪技术,可以将会话数据保存到服务器
- 存储在客户端的数据容易被窃取何截获,存在很多不安全的因素,存储在服务端相比于客户端来说就更安全
- 用户甲和用户乙都调用buyServlet将商品添加到购物车,调用payServlet进行商品结算
- 以用户甲为例进行详细说明
- 当用户甲访问购物网站时,服务器为甲创建了一个Session对象(相当于购物车)
- 当甲将iPhone手机添加到购物车时,iPhone手机的信息便存放到了Session对象中。同时,服务器将Session对象的ID属性以Cookie (Set-Cookie: JSESSIONID=111)的形式返回给甲的浏览器。
- 当甲完成购物进行结账时,需要向服务器发送结账请求,这时,浏览器自动在请求消息头中将Cookie (Cookie: JSESSIONID=111)信息发送给服务器,服务器根据ID属性找到为用户甲所创建的Session对象,并将Session对象中所存放的iPhone手机信息取出进行结算。
3.2 HttpSession API
//注意:由于getSession方法会产生发送会话标识号的cookie头字段,所以必须在发送响应内容之前调用它
/*
返回与当前请求相关的HttpSession对象,根据参数判断是否创建新的HttpSession对象
true:对象不存在是创建新的对象
false:不创建,返回null
*/
public HttpSession getSession(boolean create)
//返回与当前请求相关的HttpSession对象,相当于上面方法为true时的情况
public HttpSession getSession()
//返回与当前HttpSession对象关联的会话标识号
String getId()
//返回Session创建的时间,是创建Session的时间与1970/1/1 00:00:00之间时间差的毫秒表示
long getCreationTime()
//返回客户端最后一次发送与Session相关请求的时间
long getLastAccessedTime()
//设置当前HttpSession对象可空闲的以秒为单位的最长时间,也就是修改当前会话的默认超时间隔
void setMaxInactiveInterval(int interval)
//判断当前HttpSession对象是否是新创建的
boolean isNew()
//强制使Session对象无效
void invalidate()
//返回当前HttpSession对象所属的Web应用程序对象,即代表当前web的ServletContext对象
ServletContext getServletContext()
//将一个对象与一个名称关联后存储到当前的HttpSession对象中
void setAttribute(String name, Object value)
//从当前HttpSession对象中返回指定名称的属性值
String getAttribute()
//从当前HttpSession对象中删除指定名称的属性
void removeAttribute(String name)
3.3 Session的生命周期
-
Session生效
- Session在用户第一次访问服务器时创建;只有访问jsp、Servlet等程序时才会创建,只访问HTML,image等静态资源是不会创建的
- 调用request.getSession(true)强制生成Session
-
Session失效
- 超时限制:在一定时间内,如果客户端一直没有请求访问,那么服务器会认为客户端已经请求结束,并且将此次会话生成的HttpSession对象变成垃圾对象,等待垃圾收集器将其从内存中彻底删除;如果超时后浏览器再次向服务器发出请求访问,此时会创建一个新的HttpSession对象,并为其分配一个新的id
- 使用invalidate()方法,强制Session对象失效
-
自定义失效时间
<!--在web.xml文件中配置--> <session-config> <!--这里的30是指30分钟--> <!--如果为-1,session对象永不过期--> <session-timeout>30</session-timeout> </session-config>
3.4 Session的原理分析
-
Session是基于Cookie实现的
-
session的数据要想共享,浏览器不能关闭,所以session数据不能长期保存数据
-
Session要想实现一次会话多次请求之间的数据共享,就必须要保证多次请求获取Session的对象是同一个
-
如果是不同浏览器或者重新打开浏览器后,Session对象就不一样了
- 第一次获取Session对象时,对象会有一个唯一的标识,例如:
id:6
- 在session在存入其他数据并处理完成所有业务后,需要通过服务器响应结果给浏览器
- 服务器发现业务处理中使用了session对象,就会把唯一标识
id:6
当做一个cookie,添加Set-Cookie:JESSIONID=6
到响应头中 - 浏览器接收到响应结果后,会把cookie数据存储到浏览器的内存中
- 浏览器在同一个会话中请求访问时,会把cookie中的数据添加到请求头中发送给服务器
- 获取到请求后,从请求头中就读取cookie中的JESSIONID值为6,然后到服务器内存中寻找
id:6
的session对象,找到了就直接返回该对象,否则新创建一个session对象 - 关闭打开浏览器后,因为浏览器的cookie已被销毁,所以就没有JESSIONID的数据,所以服务端获取到的session就是一个全新的session对象
- 第一次获取Session对象时,对象会有一个唯一的标识,例如:
3.5 Session钝化与活化
-
服务器正常关闭和启动,session中的数据会被保持下来
-
钝化:在服务器正常关闭后,Tomact会自动将Session数据写入硬盘的文件中
- 钝化的数据路径为:
项目目录\target\tomcat\work\Tomcat\localhost\项目名称\SESSIONS.ser
- 钝化的数据路径为:
-
活化:再次启动服务器后,从文件中加载数据到Session中
- 数据加载到Session中后,路径中的
SESSIONS.ser
文件会被删除掉
- 数据加载到Session中后,路径中的
4. Cookie和Session小结
-
区别:
- 存储位置:Cookie存储在客户端,Session存储在服务端
- 安全性:Cookie不安全,Session安全
- 数据大小:Cookie最大3KB,Session大小无限制
- 存储时间:Cookie可以通过setMaxAge()长期存储,Session默认30分钟
- 服务器性能:Cookie不占服务器资源,Session占用服务器资源
-
应用场景:
- Cookie(保证用户在未登录情况下的身份识别):购物车,记住我功能
- Session(用来保存用户登录后的数据):以登录用户的名称展示,验证码