会话技术
# 会话跟踪技术概述
会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
- 从浏览器发出请求到服务端响应数据给前端之后,一次会话(在浏览器和服务器之间)就被建立了
- 会话被建立后,如果浏览器或服务端都没有被关闭,则会话就会持续建立着
- 浏览器和服务器就可以继续使用该会话进行请求发送和响应,上述的整个过程就被称之为会话。
实际场景:访问京东时,打开浏览器进入京东首页后浏览器和京东服务器之间就建立了一次会话,后面的搜索商品,查看商品的详情、加入购物车等都是在这一次会话中完成。
会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
- 服务器会收到多个请求,这多个请求可能来自多个浏览器
- 服务器需要用来识别请求是否来自同一个浏览器
- 服务器用来识别浏览器的过程,这个过程就是会话跟踪
- 服务器识别浏览器后就可以在同一个会话中多次请求之间来共享数据
实际场景:
- 购物车:
加入购物车和去购物车结算是两次请求,但是后面这次请求要想展示前一次请求所添加的商品,就需要用到数据共享。 - 页面展示用户登录信息:很多网站,登录后访问多个功能发送多次请求后,浏览器上都会有当前登录用户的信息[用户名],比如百度、京东、码云等。
- 网站登录页面的
记住我功能:当用户登录成功后,勾选记住我按钮后下次再登录的时候,网站就会自动填充用户名和密码,简化用户的登录操作,多次登录就会有多次请求,他们之间也涉及到共享数据。 - 登录页面的验证码功能:生成验证码和输入验证码点击注册这也是两次请求,这两次请求的数据之间要进行对比,相同则允许注册,不同则拒绝注册,该功能的实现也需要在同一次会话中共享数据。
实现技术:客户端会话跟踪技术Cookie,服务端会话跟踪技术Session
# Cookie
概念: 客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。
Cookie工作流程
- 服务端提供了两个Servlet,分别是ServletA和ServletB
- 浏览器发送HTTP请求1给服务端,服务端ServletA接收请求并进行业务处理
- 服务端ServletA在处理的过程中可以创建一个Cookie对象并将
name=zs的数据存入Cookie - 服务端ServletA在响应数据的时候,会把Cookie对象响应给浏览器
- 浏览器接收到响应数据,会把Cookie对象中的数据存储在浏览器内存中,此时浏览器和服务端就建立了一次会话
- 在同一次会话中浏览器再次发送HTTP请求2给服务端ServletB,浏览器会携带Cookie对象中的所有数据
- ServletB接收到请求和数据后,就可以获取到存储在Cookie对象中的数据,这样同一个会话中的多次请求之间就实现了数据共享
# Cookie的基本使用
常用方法
| 方法名 | 作用 |
|---|---|
| new Cookie(名字,值) | 通过构造方法创建一个Cookie,每个Cookie保存一个键和值 |
| response.addCookie(Cookie cookie) | 把Cookie发送到浏览器 |
| Cookie[] request.getCookies() | 获取浏览器端所有发送回来的Cookie数组对象 |
| setMaxAge(0) | 删除Cookie 参数值为: 1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除 2.负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁 3.零:删除对应Cookie |
遍历Cookie数组,获取每一个Cookie对象:for;使用Cookie对象方法获取数据
cookie.getName();
cookie.getValue();
2
页面中拿到Cookie的使用方式:${cookie."键名",value}
# Cookie原理分析
Cookie的实现原理是基于HTTP协议的,其中设计到HTTP协议中的两个请求头信息:
响应头:set-cookie
请求头: cookie
- 对于AServlet响应数据的时候,Tomcat服务器都是基于HTTP协议来响应数据
- 当Tomcat发现后端要返回的是一个Cookie对象之后,Tomcat就会在响应头中添加一行数据
Set-Cookie:username=zs - 浏览器获取到响应结果后,从响应头中就可以获取到
Set-Cookie对应值username=zs,并将数据存储在浏览器的内存中 - 浏览器再次发送请求给BServlet的时候,浏览器会自动在请求头中添加
Cookie: username=zs发送给服务端BServlet - request对象会把请求头中cookie对应的值封装成一个个Cookie对象,最终形成一个数组
- BServlet通过Request对象获取到Cookie[]后,就可以从中获取自己需要的数据
# Cookie使用细节
cookie存活时间
默认情况下,Cookie 存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
相关API:setMaxAge(int seconds):设置Cookie存活时间,单位是秒
参数
- 正数:将 Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
- 负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则 Cookie被销毁
- 零:删除对应 Cookie
Cookie存储中文字符
浏览器只识别URL编码的字符,所以需要先将中文字符转码成URL
示例
String value = "张三";
// 对中文进行URL编码
value = URLEncoder.encode(value, "UTF-8");
System.out.println("存储数据:"+value);
// 将编码后的值存入Cookie中
Cookie cookie = new Cookie("username",value);
// 设置存活时间 ,1周 7天
cookie.setMaxAge(60*60*24*7);
//cookie.setMaxAge(604800); //不易阅读(可以使用注解弥补),程序少进行一次计算
// 2. 发送Cookie,response
response.addCookie(cookie);
// 注意:获取到的数据需要再使用UTF-8解码才能获取到原来的字符
String username = URLDecoder.decode(username,"UTF-8");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Tomcat8.0之后是允许直接往cookie中存储中文的,但是键不能为中文,值可以是中文
# Session
概念: 服务端会话跟踪技术:将数据保存到服务端。
- Session是存储在服务端而Cookie是存储在客户端
- 存储在客户端的数据容易被窃取和截获,存在很多不安全的因素
- 存储在服务端的数据相比于客户端来说就更安全
Session工作流程
- 在服务端的AServlet获取一个Session对象,把数据存入其中
- 在服务端的BServlet获取到相同的Session对象,从中取出数据
- 就可以实现一次会话中多次请求之间的数据共享了
# Session的基本使用
在JavaEE中提供了HttpSession接口,来实现一次会话的多次请求之间数据共享功能。
使用:
获取Session对象,使用的是request对象
HttpSession session = request.getSession();
Session对象提供的功能:
| 方法名 | 作用 |
|---|---|
| request.getSession() | 通过请求对象获取会话对象,第一次是创建,以后是获取 |
| session.getId() | 获取用户(客户端/浏览器)唯一会话id |
| session.setAttribute("键", 值) | 设置值 |
| session.getAttribute("键") | 获取值 |
| session.removeAttribute("键") | 删除值 |
| session.setMaxInactiveInterval() | 设置会话过期时间 |
| session.getMaxInactiveInterval() | 获取会话过期时间 |
| session.invalidate() | 使会话失效 |
# Session原理分析
Session是基于Cookie实现的。
Session实现数据共享的前提条件:保证多次请求中获取的Session对象是同一个
原理:
- demo1在第一次获取session对象的时候,session对象会有一个唯一的标识,假如是
id:10 - demo1在session中存入其他数据并处理完成所有业务后,需要通过Tomcat服务器响应结果给浏览器
- Tomcat服务器发现业务处理中使用了session对象,就会把session的唯一标识
id:10当做一个cookie,添加Set-Cookie:JESSIONID=10到响应头中,并响应给浏览器 - 浏览器接收到响应结果后,会把响应头中的coookie数据存储到浏览器的内存中
- 浏览器在同一会话中访问demo2的时候,会把cookie中的数据按照
cookie: JESSIONID=10的格式添加到请求头中并发送给服务器Tomcat - demo2获取到请求后,从请求头中就读取cookie中的JSESSIONID值为10,然后就会到服务器内存中寻找
id:10的session对象,如果找到了,就直接返回该对象,如果没有则新创建一个session对象 - 关闭打开浏览器后,因为浏览器的cookie已被销毁,所以就没有JESSIONID的数据,服务端获取到的session就是一个全新的session对象
结论: 等于是servlet提交了一个存放session对象id标识的cookie到浏览器,浏览器在下一次请求中将这个id标识再回传给另一个servlet,使得servlet能通过这个id标识找到session域中的这个session对象
# Session使用细节
Session 钝化、活化:
- 钝化:在服务器正常关闭后, Tomcat会自动将 Session数据写入硬盘的文件中
钝化的数据路径为: Maven-Tomact7:
项目目录\target\tomcat\work\Tomcat\localhost\项目名称\SESSIONS.ser手动部署的Tomcat:在控制台打印的CATALINA_BASE路径下的sessions文件夹中
- 活化:再次启动服务器后,从文件中加载数据到Session中
数据加载到Session中后,路径中的SESSIONS.ser文件会被删除掉
注意:
- session钝化和活化的前提:正常关闭服务器
- 浏览器被关闭启动后,重新建立的连接就已经是一个全新的会话,获取的session数据也是一个新的对象
- session的数据要想共享,必须保证是同一个会话,也就是浏览器不能关闭,所以session的数据不能长期保存
- cookie是存储在客户端,是可以长期保存
IDEA使用Tomcat需要手动开启重启时保留会话
Session 销毁:
- 默认情况下,无操作,30分钟自动销毁
失效时间可以在web.xml中配置
<session-timeout>30</session-timeout>
- 调用 Session对象的
invalidate()方法手动销毁
补充:session.getMaxInactiveInterval():获取Session过期时间API
# Cookie和Session的区别
- 存储位置:Cookie 是将数据存储在客户端,Session 将数据存储在服务端
- 安全性:Cookie不安全,Session相对安全
- 数据大小:Cookie最大3KB,Session无大小限制
- 存储时间:Cookie可以通过setMaxAge()长期存储,Session默认30分钟
- 服务器性能:Cookie不占服务器资源,Session占用服务器资源
应用场景:
- 购物车:使用Session来存储
- 登录用户的名称展示:使用Session来存储
- 记住我功能:使用Cookie来存储
- 验证码:使用session来存储
结论
- Cookie是用来保证用户在未登录情况下的身份识别
- Session是用来保存用户登录后的数据
# 域对象
JavaWeb中有四大域对象,分别是:
- page:当前页面有效
- request:当前请求有效
- session:当前会话有效
- application:当前应用有效
EL 表达式获取数据,会依次从这4个域中寻找,直到找到为止。而这四个域对象的作用范围如下图所示

例如: ${brands},EL 表达式获取数据,会先从page域对象中获取数据,如果没有再到 requet 域对象中获取数据,如果再没有再到 session 域对象中获取,如果还没有才会到 application 中获取数据。
request,一个用户可有多个;
session,一个用户一个;
servletContext(application),所有用户共用一个。所以,为了节省空间,提高效率,ServletContext中,要放必须的、重要的、所有用户需要共享的线程又是安全的一些信息。