会话简介
在计算机领域中,是存在会话的,客户端与服务器之间的一次通话就称为会话。当打开浏览器访问一个地址请求成功后就意味着开启了一个新的会话,会话期间可以多次访问站点内的其他资源,这样实际都是在一个会话中操作,直到浏览器关闭,表示此次会话结束。
会话是一个客户与服务器之间的不中断的请求响应序列。
会话技术分类
- 客户端会话:Cookie
- 服务器会话:Session
会话作用
因为HTTP协议是无状态的,所以很显然服务器不可能知道我们已经在上一次的HTTP请求中通过了验证。当然,最简单的解决方案就是所有的请求里面都带上用户名和密码,这样虽然可行,但大大加重了服务器的负担(对于每个request都需要到数据库验证),也大大降低了用户体验(每个页面都需要重新输入用户名密码,每个页面都带有登录表单)。既然直接在请求中带上用户名与密码不可行,那么就只有在服务器或客户端保存一些类似的可以代表身份的信息了,所以就有了cookie与session,cookie和session用来跟踪用户的整个会话。
客户端会话cookie
理解
- 在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
- 而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。
原理
- Cookie是解决HTTP无状态性的有效手段,服务器可以设置或读取Cookie中所包含的信息。当用户登录后,服务器会发送包含登录凭据的Cookie到用户浏览器客户端,而浏览器对该Cookie存储在硬盘C:\Users\用户名\AppData\Local\Google\Chrome\User Data\Default)。用户再次访问该网站时,浏览器会发送该Cookie到服务器,服务器对该凭据进行验证,合法时使用户不必输入用户名和密码就可以直接登录。
- 本质上讲,Cookie是一段文本信息。客户端请求服务器时,如果服务器需要记录用户状态,就在响应用户请求时发送一段Cookie信息。客户端浏览器保存该Cookie信息,当用户再次访问该网站时,浏览器会把Cookie做为请求信息的一部分提交给服务器。服务器检查Cookie内容,以此来判断用户状态,服务器还会对Cookie信息进行维护,必要时会对Cookie内容进行修改。
总结
- 当从浏览器发送请求到服务器后,servlet创建cookie,保存少量数据,发送浏览器
- 浏览器获得服务器发送的cookie数据,将自动的保存到浏览器端
- 下次访问时,浏览器将自动携带cookie数据发送给服务器。
语法
-
创建cookie:new Cookie(str,str)
-
将cookie响应给浏览器:addCookie(cookie)
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 9:45 */ /* * 创建cookie * 第一次访问创建cookie,在响应头中 * 再次请求在请求头中 * * */ @WebServlet("/c1") public class Cookie_Demo01 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //创建cookie URLEncoder.encode 编码 Cookie c = new Cookie("msg", URLEncoder.encode("少壮不努力,老大徒伤悲","utf-8")); //允许tomcat下所有项目都携带 c.setPath("/"); //将cookie响应会浏览器 resp.addCookie(c); } }
-
获取浏览器携带的所有的cookie:Cookies[] getCookies()
-
返回cookie键:String getName()
-
返回cookie值:String getValue()
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLDecoder; import java.net.URLEncoder; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 10:14 */ /* * req.getCookies(); 获取浏览器携带的所有的cookie * * cookie.getName() 返回cookie键 * cookie.getValue()返回cookie值 * */ @WebServlet("/c2") public class Cookie_Demo02 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取浏览器携带的所有的cookie URLDecoder.decode 解码 Cookie[] cookies = req.getCookies(); if (cookies != null){ for (Cookie cookie : cookies) { System.out.println(cookie.getName()+"\t"+ URLDecoder.decode(cookie.getValue(),"utf-8")); } } } }
-
浏览器只会携带本项目的所有cookie到达服务器
setPath(request.getContextPath()) 默认是当前项目
/:部署在当前服务器下所有的项目都携带 -
设置最大存活时间 默认是浏览器关闭销毁
setMaxAge(秒)import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 10:26 */ /* *创建cookie带生存时间的cookie * */ @WebServlet("/c3") public class Cookie_Demo03 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //创建cookie URLEncoder.encode 编码 Cookie c = new Cookie("msg", URLEncoder.encode("书山有路勤为径,学海无涯苦作舟","utf-8")); //设置cookie存活时间 一小时 c.setMaxAge(60*60); //将cookie响应会浏览器 resp.addCookie(c); } }
清空持久化cookie
特点
- Cookie中只能以键值对的形式保存字符串类型的数据
- Cookie中保存的数据有大小限制,一般不超过4kb
- Cookie是保存在客户端的,安全性较差
- Cookie默认有效期是浏览器关闭即销毁,若持久化保存Cookie对象,要设置有效期
使用场景
- 记住用户名
- 历史记录
服务器端会话session
理解
- Session是服务器提供的一个会话对象,是第二大作用域对象。创建之后这个Session是存储到服务器中的。但Session的使用需要和浏览器建立关联(session底层是基于cookie进行实现的),这个关联与Cookie有关,其中每一个Session对象都会对应一个sessionId,这个sessionId就被存储在Cookie中。
原理
- 当用户第一次请求服务器存储数据的时候服务器会为每一个用户都创建一个session对象来去保存用户私有的数据,每一个session都有一个唯一的JSESSIONID。这个id保存在每一个用户的浏览器上,当用户再次访问服务器的时候就会携带该用户JSESSIONID去服务端找到与之对应的session对象
使用
-
获取session对象:HttpSession session = request.getSession();
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 14:07 */ /* * api * request * HttpSession getSession() 获取|创建一个session * */ @WebServlet("/s1") public class Session_Demo01 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取|创建一个session HttpSession session = req.getSession(); session.setAttribute("msg","我是大帅哥"); } }
-
保存数据到session中:session.setAttribute(String 绑定名,Object 绑定值)
-
获取session数据:session.getAttribute("绑定名")
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 14:07 */ /* * api * request * HttpSession getSession() 获取|创建一个session * */ @WebServlet("/s2") public class Session_Demo02 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取|创建一个session HttpSession session = req.getSession(); Object msg = session.getAttribute("msg"); System.out.println(msg); } }
-
销毁session对象:session.invalidate();
特点
- 存储在服务器端
- 默认存储30分钟
- Session做第二大域对象,在一个会话范围内的数据是科共享的
- Session存储的数据可以是任意类型
假死现象
-
浏览器关闭服务器中的session找不到了造成session假死现象、但是它并不意味着session销毁、因为session本身是在服务器存储着、只不过浏览器的cookie中存储的JSESSION丢失了,造成无法匹配到服务器中session。
-
服务器关闭session也不会消失 因为session有默认存活时间30分钟。当未到达30分钟服务器突然宕机,此时tomcat在6.x版本后引入自动备份机制。服务器停止此时服务器会将session中的内容序列化(钝化)到硬盘上、当服务器再次启动时候就会从硬盘上读取反序列化(活化)session内容到内存中。
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/8/19 14:07 */ /* * session 持久化 * 就是将cookie进行持久化,让浏览器关闭的时候不丢失JSESSIONID * */ @WebServlet("/s3") public class Session_Demo03 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取|创建一个session HttpSession session = req.getSession(); //设置cookie里保存sessionid Cookie c = new Cookie("JSESSIONID", session.getId()); //设置cookie最大保留时间 c.setMaxAge(60*30); //将cookie响应浏览器 resp.addCookie(c); session.setAttribute("msg","大家都是大帅哥"); } }
使用场景
- 用户登录时安全校验
- 购物车
Cookie和Session的区别
数据存储位置上
- cookie数据存储在浏览器
session数据存储在服务器
安全性
- cookie不太安全
session比较安全
存储数据大小
- cookie最大只允许存储4kb
session存储数据无限制
数据类型
- cookie键和值都是字符串
session键是字符串值可以是任意类型