
一背景HTTP 协议是无状态的。服务器不会记住上一次是谁访问的。比如登录完刷新页面服务器不知道你是谁。Cookie、Session 就是用来保存会话状态记住用户。无状态默认情况下 HTTP 协议的客⼾端和服务器之间的这次通信, 和下次通信之间没有直接的联系.二CookieCookie 是服务器发给浏览器浏览器保存在本地的一小段文本数据。浏览器之后每次访问同一个网站会自动带上这个 Cookie 发给服务器。工作流程1.浏览器第一次访问服务器没有 Cookie2.服务器响应的时候通过响应头 Set‑Cookie把 Cookie 返回给浏览器3.浏览器把 Cookie 存到本地内存 / 磁盘4.之后浏览器再访问该网站请求头自动带上 Cookie 发给服务器5.服务器读取 Cookie识别这个用户获取Cookie的方式1.通过HttpServletRequest得到request获取CookieRequestMapping(/getCookie)publicStringgetCookie(HttpServletRequestrequest){Cookie[]cookiesrequest.getCookies();if(cookies!null){for(Cookiecookie:cookies){System.out.println(cookie.getName()cookie.getValue());}}return获取cookie成功;}2.通过注解CookieValue()填入需要的Cookie 的keyRequestMapping(/getCookie2)publicStringgetCookie(CookieValue(hhh)Stringhhh){return获取Cookie成功, bit:hhh;}需注意方法二中的CookieValue 默认必填CookieValue(“hhh”)默认要求请求必须携带名为hhh的 Cookie如果浏览器没有这个 cookie直接报 400 异常。解决方法a.设置required false允许为 null:CookieValue(value hhh, required false) String hhhb.设置默认值defaultValue:CookieValue(value hhh, defaultValue ) String hhh只要设置了 defaultValuerequired 自动变成 false不需要手动写 requiredfalse而且CookieValue 也可以直接注入Cookie对象不只是字符串 value//拿到完整Cookie对象可以获取name、value、maxAge等 CookieValue(value hhh,required false) Cookie hhhCookie三Session:Session 是服务器端保存的用户会话数据浏览器只保存一个 SessionID会话标识用来和服务器的 Session 做匹配。浏览器每次访问同一个网站会自动携带 SessionID服务器通过这个 ID 找到对应的服务端会话数据。工作流程浏览器第一次访问服务器没有 Session 相关信息服务器接收到请求创建一个 Session 对象生成唯一的 SessionID通过响应头 Set‑Cookie把携带 SessionID 的 Cookie 返回给浏览器浏览器把这个存储 SessionID 的 Cookie 存到本地内存之后浏览器再访问该网站请求头自动带上这个 Cookie里面存放 SessionID发给服务器服务器读取请求中的 SessionID根据 ID 在服务器内存 / 存储中找到对应的 Session 对象读取该用户的会话数据创建session的方式1.通过HttpServletRequestRequestMapping(/setSession)publicStringsetSession(HttpServletRequestrequest,Stringname){//获取sessionHttpSessionsessionrequest.getSession();//传输多个请求session.setAttribute(name,name);session.setAttribute(age,18);session.setAttribute(userInfo,newPerson(zhangsan,1,17));return设置session成功;}获取session的方式1.通过HttpServletRequestRequestMapping(“/getSession”)public String getSession(HttpServletRequest request){//获取sessionHttpSession session request.getSession(false);if (session ! null){System.out.println(“name:” session.getAttribute(“name”));System.out.println(“userInfo:” session.getAttribute(“userInfo”));}return “获取Session成功, name:” session.getAttribute(“name”);}2.通过SessionAttribute(“”)注解SpringMVC 从 Session 域中取出 key name的值直接注入到方法参数nameRequestMapping(/getSession2)publicStringgetSession2(SessionAttribute(name)Stringname){return获取Session成功, name:name;}3.通过HttpSession直接在方法上写参数HttpSession sessionSpringMVC 会自动帮你拿到 session 对象等价于HttpSession session request.getSession(true);RequestMapping(/getSession3)publicStringgetSession3(HttpSessionsession){return获取Session成功, name:session.getAttribute(name);}补SpringMVC 三种获取 Session 方式总结方式一request.getSession (false)代码HttpSession session request.getSession (false);特点没有 session 时返回 null不会自动创建 session。风险session 为 null 时调用 getAttribute () 会直接空指针异常。适用场景判断会话是否存在不想凭空创建 session。方式二SessionAttribute (“name”) 注解注入属性代码public String test (SessionAttribute (“name”) String name)特点直接从 session 取出指定 key 的属性注入参数。风险默认 requiredtruesession 中没有该属性直接抛出异常 500需要手动设置 requiredfalse缺失时参数为 null。适用场景简洁获取 session 中的某个属性值。注意不要和类注解 SessionAttributes 混淆二者功能不同。方式三直接方法参数注入 HttpSession代码public String test (HttpSession session)特点等价 request.getSession (true)没有 session 就自动新建 session 对象session 永远不为 null。风险session 对象不为 null但 getAttribute () 拿到的值可能为 null字符串拼接只会输出 null 文本不会空指针访问接口就会生成 JSESSIONID会凭空创建会话占用服务端内存。适用场景需要读写 session允许创建会话。