一、会话跟踪技术的概述
1.1、会话的概念
用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
从浏览器发出请求到服务端响应数据给前端之后,一次会话(在浏览器和服务器之间)就被建立了,会话被建立后,如果浏览器或服务端都没有被关闭,则会话就会持续建立着。浏览器和服务器就可以继续使用该会话进行请求发送和响应,上述的整个过程就被称之为会话。
用实际场景来理解下会话,比如在我们访问京东的时候,当打开浏览器进入京东首页后,浏览器和京东的服务器之间就建立了一次会话,后面的搜索商品,查看商品的详情,加入购物车等都是在这一次会话中完成。
下图中一共建立了3次会话,每个浏览器都会与服务端建立一个会话,中间的第二次会话中,包含两次请求和响应。
1.2、会话跟踪的概念
服务器会收到多个请求,这多个请求可能来自多个浏览器,如上图中的6个请求来自3个浏览器。服务器需要用来识别请求是否来自同一个浏览器,服务器用来识别浏览器的过程,这个过程就是会话跟踪。服务器识别浏览器后就可以在同一个会话中多次请求之间来共享数据。
1.3 、会话跟踪在实际中的应用
我们打开京东的网站,将商品加入购物车和去购物车结算
是两次请求,购物车结算的时候需要展示加入购物车的商品,
就需要用到数据共享。
1.4、会话跟踪的实现
浏览器和服务器之间使用的是HTTP请求来进行数据传输,HTTP协议是无状态的,HTTP协议设计成无状态的目的是让每次请求之间相互独立,互不影响。所以每次浏览器向服务器请求时,服务器都会将该请求视为新的请求。所以现在浏览器和服务器不支持数据共享。
为了解决浏览器和服务器不支持数据共享的问题,具体的实现方式有:Cookie(客户端会话跟踪技术)、Session(服务端会话跟踪技术)。
二、Cookie
2.1、Cookie的概念
客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。
2.2、Cookie的案例
服务端提供了两个Servlet,分别是ServletA和ServletB,浏览器发送HTTP请求1给服务端,服务端ServletA接收请求并进行业务处理。服务端ServletA在处理的过程中可以创建一个Cookie对象并将name=zs
的数据存入Cookie,服务端ServletA在响应数据的时候,会把Cookie对象响应给浏览器。浏览器接收到响应数据,会把Cookie对象中的数据存储在浏览器内存中,此时浏览器和服务端就建立了一次会话。
在同一次会话中浏览器再次发送HTTP请求2给服务端ServletB,浏览器会携带Cookie对象中的所有数据,ServletB接收到请求和数据后,就可以获取到存储在Cookie对象中的数据,这样同一个会话中的多次请求之间就实现了数据共享。
2.3、代码的实现
2.3.1、创建Maven项目cookie-demo,并在pom.xml添加依赖
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!--jstl-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
2.3.2、编写Servlet类,名称为AServlet
在Servlet中创建Cookie对象,存入数据,发送给前端
@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//发送Cookie
//1. 创建Cookie对象
Cookie cookie = new Cookie("username","zs");
//2. 发送Cookie,response
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
2.3.3、启动项目,并在页面访问:http://localhost:8080/cookie-demo/aServlet
在chrome浏览器通过开发者工具包查看Cookie的值
2.3.4、编写一个新Servlet类,名称为BServlet
在页面访问:http://localhost:8080/cookie-demo/bServlet
@WebServlet("/bServlet")
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取Cookie
//1. 获取Cookie数组
Cookie[] cookies = request.getCookies();
//2. 遍历数组
for (Cookie cookie : cookies) {
//3. 获取数据
String name = cookie.getName();
if("username".equals(name)){
String value = cookie.getValue();
System.out.println(name+":"+value);
break;
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
在IDEA控制台就能看到输出的结果:
2.3.5、Cookie的原理分析
AServlet返回的响应数据是Cookie对象,当Tomcat发现后端要返回的是一个Cookie对象之后,Tomcat就会在响应头中添加一行数据Set-Cookie:username=zs,
浏览器获取到响应结果后,从响应头中就可以获取到Set-Cookie
对应值username=zs
,并将数据存储在浏览器的内存中。浏览器再次发送请求给BServlet的时候,浏览器会自动在请求头中添加Cookie: username=zs
发送给服务端BServlet
三、Session
3.1、session的概念
服务端会话跟踪技术:将数据保存到服务端
3.2、通过session实现会话
在服务端的AServlet获取一个Session对象,把数据存入其中。在服务端的BServlet获取到相同的Session对象,从中取出数据。就可以实现一次会话中多次请求之间的数据共享了
3.3、代码的实现
创建SessionDemo1:获取Session对象、存储数据
@WebServlet("/demo1")
public class SessionDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//存储到Session中
//1. 获取Session对象
HttpSession session = request.getSession();
//2. 存储数据
session.setAttribute("username","zs");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
创建SessionDemo2:获取Session对象、获取数据
@WebServlet("/demo2")
public class SessionDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取数据,从session中
//1. 获取Session对象
HttpSession session = request.getSession();
//2. 获取数据
Object username = session.getAttribute("username");
System.out.println(username);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
先访问http://localhost:8080/cookie-demo/demo1
,将数据存入Session
再访问http://localhost:8080/cookie-demo/demo2
,从Session中获取数据
查看控制台
通过案例的效果,能看到Session是能够在一次会话中两次请求之间共享数据。
3.4、session原理分析
Session是基于Cookie实现的
1、通过浏览器访问 http://localhost:8080/cookie-demo/demo1时,demo1在第一次获取session对象的时候,session对象会有一个唯一的标识,假如是id:10
,demo1在session中存入其他数据并处理完成所有业务后,需要通过Tomcat服务器响应结果给浏览器。浏览器接收到响应结果后,会把响应头中的coookie数据存储到浏览器的内存中。
2、浏览器在同一会话中访问demo2的时候,会把cookie中的数据按照cookie: JESSIONID=10
的格式添加到请求头中并发送给服务器Tomcat
3、demo2获取到请求后,从请求头中读取cookie中的JSESSIONID值为10,然后就会到服务器内存中寻找id:10
的session对象,如果找到了,就直接返回该对象,如果没有则新创建一个session对象 。
总结:浏览器会把存入数据的session的id当做cookie存到响应头中,在同一次会话时,会把这个cookie添加到请求头,发送第二次请求时,会携带这个cookie,服务器通过session的id找到对应的session,然后从session中取出相应的值。
之所以说session是基于cookie实现的,因为session的id是当做cookie进行存储的。
四、 cookie和session的区别
1、Session是存储在服务端而Cookie是存储在客户端
2、存储在客户端的数据容易被窃取和截获,存在很多不安全的因素
3、存储在服务端的数据相比于客户端来说就更安全