文章目录
-
- [一、Cookie/Session 简介](#一、Cookie/Session 简介)
- [二、Cookie 和 Session 的区别](#二、Cookie 和 Session 的区别)
- 三、获取Cookie
- [四、获取 Session](#四、获取 Session)
- 五、结语
一、Cookie/Session 简介
- 理解Cookie
在Http协议中,他自身是无状态协议。也就是在默认情况下Http 客户端和服务器之间的这次通信,和下次通信之间没有直接的联系。
但是在开发中,有时需要知道请求之间的关联关系,例如:在登录网页成功后,第二次访问时服务器就知道该请求是否已经过了,也就不需要再次登录一遍了。
这种关系,就相当于服务器给了客户端一个" 令牌 ",而这个" 令牌 "就存储在Cookie中。并且此时服务器记录该" 令牌 "信息,以及对应的用户信息,记录这个工作就是Session在做的工作。当客户端访问具体页面时,就会带上这个" 令牌 ",服务器通过" 令牌 "就可以响应对应的页面内容。

- 理解会话
会话是⼀个客户与服务器之间的不中断的请求响应。对客户的每个请求,服务器能够识别出请求来自于同一个客户。当一个新客户发送第一个请求时开始一个会话,当客户结束会话或者在时限内客户没有再发送过请求,那么这个会话结束。 - 理解Session
服务器同一时刻收到的请求是很多的。服务器需要清楚的区分每个请求是属于哪个用户,也就是属于哪个会话,就需要在服务器这边记录每个会话以及与用户的信息的对应关系。
Session是服务器为了保存用户信息而创建的⼀个特殊的对象。

Session 的本质类似一个" 哈希表 ",存储了键值对结构,Key 就是SessionID,Value就是用户信息。上述例子所说的" 令牌 "就是可以看做SessionID,除了SessionID之外还可以存储一些其他信息,时间等等。

- Cookie和Session的使用:
- 当用户登录时,服务器在Session 中新增一个记录,并将SessionID 返回给客户端(通常是通过Set-Cookie字段返回)。
- 客户端在后续给服务器发送请求时,就会在请求中带上SessionID(通过Cookie字段带上)。
- 服务器接收到请求后,根据请求中的SessionID 在session中获取到对应的用户信息;在进行后续操作,如果找不到则重新创建并将SessionID返回。

二、Cookie 和 Session 的区别
- Cookie 是客户端保存用户信息的一种机制,Session 是服务器端保存用户信息的一种机制。
- Cookie 和 Session 之间主要是通过 SessionId 关联起来的,SessionId 是 Cookie 和 Session 之间的桥梁。
- Cookie 和 Session 经常会在一起配合使用,但不是必须配合:
(1) 完全可以用 Cookie 来保存一些数据在客户端,这些数据不一定是用户身份信息,也不一定是 SessionId。
(2)Session 中的 sessionId 也不需要非得通过 Cookie/Set-Cookie 传递,比如通过 URL 传递
三、获取Cookie
传统获取,示例:
java
@RestController
@RequestMapping("/request2")
public class Request2Controller {
@RequestMapping("/getCookie")
public String getCookie(HttpServletRequest request){
Cookie[] cookies = request.getCookies();
if (cookies != null){
for (Cookie cookie : cookies){
System.out.println(cookie.getName() + ": " + cookie.getValue());
}
}
return "获取cookie成功";
}
}
HttpServletRequest 和 HttpServletResponse 是Spring MVC 方法的内置对象,HttpServletRequest 对象表示客户端的请求,http 请求头中所有信息都封装在这个对象中,通过该对象的方法可以获得客户端请求的所有信息。
HttpServletResponse 对象代表服务器的响应,Http 响应的信息都封装在这个对象中,通过该对象的方法可以获得服务器响应的所有内容。
Spring MVC 对这两个对象基础上进行了封装,提供了更简单的方法。
此时没有Cookie,所以返回的为Null,通过手动设置Cookie,并在浏览器访问可以得到,在控制台输出。由此Cookie是可以伪造的,所以不安全,在使用Cookie时,要在后端进行Cookie检验。



简洁获取:
可以通过 @CookieValue 注解获取Cookie,示例:
java
@RestController
@RequestMapping("/request2")
public class Request2Controller {
@RequestMapping("/getCookie2")
public String getCookie(@CookieValue String name){
return "获取到cookie :" + name;
}
}
通过浏览器访问:

四、获取 Session
Session 是服务器端的机制,需要先存储然后进行获取。Session 也是通过 HttpServletRequest 进行存储和获取。
- 设置Session
java
@RestController
@RequestMapping("/request2")
public class Request2Controller {
@RequestMapping("/setSession")
public String setSession(HttpServletRequest request,String name){
HttpSession session = request.getSession();
session.setAttribute("name",name);
session.setAttribute("age",18);
session.setAttribute("userInfo",new Person("zhangsan",17,1));
return "设置session成功";
}
}
在浏览器中访问接口:会有一个SessionID创建。

- 传统获取Session,示例:
java
@RestController
@RequestMapping("/request2")
public class Request2Controller {
@RequestMapping("/getSession")
public String getSession(HttpServletRequest request){
//获取session
HttpSession session = request.getSession();
if(session != null){
System.out.println(session.getAttribute("name"));
System.out.println(session.getAttribute("age"));
System.out.println("userInfo" + session.getAttribute("userInfo"));
}
return "获取session成功,name: " + session.getAttribute("name");
}
}
通过浏览器访问url:http://127.0.0.1:8080/request2/getSession

通过postman 访问:

简洁获取Session:通过@SessionAttribute 注解获取,示例:
java
@RestController
@RequestMapping("/request2")
public class Request2Controller {
@RequestMapping("/getSession2")
public String getSession2(@SessionAttribute String name){
return "获取session成功,name: " + name;
}
}
但是如果参数较多的情况下,需要列出的参数也很多,因此可以使用下面的方式获取,介于第一种和第二种之间,更简洁且获取多个参数不需要将多个参数都列出。Session不存在的话会自动创建。
java
@RestController
@RequestMapping("/request2")
public class Request2Controller {
@RequestMapping("/getSession3")
public String getSession3(HttpSession session){
return "获取session成功,name: " + session.getAttribute("name");
}
}
浏览器访问结果:

五、结语
本次分享围绕 Spring Web MVC 中 Cookie 与 Session 展开:从基础概念明确了二者是 HTTP 无状态协议下实现状态管理的核心工具,再到差异对比理清了 "客户端存储" 与 "服务端存储" 的适用场景,最后通过实战示例掌握了具体的获取方式。