文章目录
会话管理:Cookie与Session
HTTP是无状态,有会话的
无状态:同一个连接中,两个执行成功的请求之间是没有关系的
解决方法:cookies
Cookie
Cookie定义:(又名 HTTP Cookie 或 Web Cookie)服务器发送到用户浏览器 并保存在本地的一小块数据,会在浏览器下次向同一服务器再发送请求时被携带并发送到服务器上。(自动保存,自动发送)
cookie一般要设置的两个属性:
-
生效的范围
原因:某些路径需要cookie,某些路径不需要
-
生存时间
cookie默认存在浏览器中,浏览器关闭cookie失效
设置生存时间后,cookie存在硬盘中,浏览器关闭cookie不失效,超过时间才失效
设置Cookie
@RequestMapping(path = "/cookie/set", method = RequestMethod.GET)
@ResponseBody
public String setCookie(HttpServletResponse response) {
// 创建cookie
Cookie cookie = new Cookie("code", CommunityUtil.generateUUID());
// 设置cookie生效的范围(原因:某些路径需要cookie,某些路径不需要)
cookie.setPath("/community/alpha");
// 设置cookie的生存时间
// cookie默认存在浏览器中,浏览器关闭cookie失效
// 设置生存时间后,cookie存在硬盘中,浏览器关闭cookie不失效,超过时间才失效
cookie.setMaxAge(60 * 10);
// 发送cookie
response.addCookie(cookie);
return "set cookie";
}
获取Cookie
利用注解获取
@RequestMapping(path = "/cookie/get", method = RequestMethod.GET)
@ResponseBody
// @CookieValue("code"):通过key名获取对应的cookie
public String getCookie(@CookieValue("code") String code) {
System.out.println(code);
return "get cookie";
}
从Request中获取
public String getCookie(HttpServletRequest request,String name){
// 1. 判空
if(request==null || name==null){
throw new IllegalArgumentException("参数为空!");
}
// 2. 获取所有Cookie(可能没有Cookie,空数组)
Cookie[] cookies = request.getCookies();
// 3. 遍历Cookie,判断是否有目标key
if(cookies!=null){
for(Cookie cookie:cookies){
if(cookie.getName().equals(name)){
return cookie.getValue();
}
}
}
return null;
}
缺点:
- 不安全。存在客户端的数据安全程度不如服务器,容易被盗,也因此不能存一些敏感的数据
- 性能低。在多数请求中会自动将cookie发送给服务器,增加服务器的数据量,对性能产生影响
- 只能存少量数据
Session
Session不是HTTP的标准,是JavaEE的标准
Session是服务端对象,用于在服务端记录客户端信息。
数据存放在服务端更安全,但会增加服务端的内存压力
Session依赖于Cookie
服务器端会自动创建Session,并注入进HttpSession对象中,不需要手动创建
与resquest、response、model等对象使用方法相同,只需要声明,SpringMVC就会注入
cookie只能存字符串类型数据,因为浏览器只能解析字符串类型
session在服务器端,可以存储任意类型数据
设置Session
@RequestMapping(path = "/session/set", method = RequestMethod.GET)
@ResponseBody
// 服务器端会自动创建Session,并注入进HttpSession对象中,不需要手动创建
// 与resquest、response、model等对象使用方法相同,只需要声明,SpringMVC就会注入
// cookie只能存字符串类型数据,因为浏览器只能解析字符串类型
// session在服务器端,可以存储任意类型数据
public String setSession(HttpSession session) {
session.setAttribute("id", 1);
session.setAttribute("name", "Test");
return "set session";
}
获取Session
@RequestMapping(path = "/session/get", method = RequestMethod.GET)
@ResponseBody
public String getSession(HttpSession session) {
System.out.println(session.getAttribute("id"));
System.out.println(session.getAttribute("name"));
return "get session";
}
总结
1)用Cookie还是Session要根据情况决定,没必要存的数据就都不用
2)能用Cookie就用Cookie,可以减小服务端压力
3)Session如果是单体应用,即只部署一台服务器时,可以随便使用。而部署到多台服务器时,即分布式部署,分布式框架中很少用Session,原因如下
存在问题:Session共享问题
解决方案:
-
黏性Session:设置代理的负载均衡策略,同一个IP发来的请求,都用同一个服务器进行处理。
缺点很难保证服务器之间是负载均衡的,性能不好
-
同步Session:在一个服务器上设置的Session会同步给其他服务器,所有服务器都会有相同的Session
缺点:同步操作会对服务器性能产生影响,且服务器与服务器之间会产生关联(耦合),就不独立了
-
共享Session:单独用一个服务器存放Session,所有Session都会发送到这台服务器并存储,其他服务器不存储。当需要用到Session时,都会向这台服务器申请Session。
缺点:若存放Session的单体服务器坏了,其他服务器就无法工作了
-
数据库集群:能使用Cookie就尽量用,而一些敏感数据可以存在数据库集群中。(数据库集群很常见)
缺点:数据库数据在硬盘中,和内存相比,读取数据的速度会更慢。且并发时可能出现一些问题
-
Redis集群(推荐):可以将传统的SQL数据库集群,替换成NoSQL数据库,如Redis。
一些选择题
C
D
W5bhpE18-1709222488906)]
一些选择题
[外链图片转存中…(img-e19Fcoma-1709222488907)]
C
[外链图片转存中…(img-eMB8YzkI-1709222488908)]
D
[外链图片转存中…(img-dZRUsr36-1709222488908)]
C