文章目录
- 🎍Cookie简介
- 🍀理解Session
- 🌳Cookie 和 Session 的区别
- 🌲获取Cookie
- 🌸传统获取Cookie
- 🌸简洁获取Cookie
- 🌴获取Session
- 🌸Session存储
- 🌸Session读取
- 🌻传统读取Session
- 🌻简洁获取Session
- ⭕总结
🎍Cookie简介
HTTP 协议⾃⾝是属于 "⽆状态"协议.
"⽆状态"的含义指的是:
- 默认情况下 HTTP 协议的客⼾端和服务器之间的这次通信,和下次通信之间没有直接的联系.但是实际开发中,我们很多时候是需要知道请求之间的关联关系的.
例如登陆⽹站成功后,第⼆次访问的时候服务器就能知道该请求是否是已经登陆过了.
想要了解详情的可以看博主写的【网络原理】HTTP 请求 (Request)详解
上述图中的 “令牌” 通常就存储在 Cookie 字段中 ⽐如去医院挂号
- 看病之前先挂号. 挂号时候需要提供⾝份证号, 同时得到了⼀张 “就诊卡”, 这个就诊卡就相当于患 者的 “令牌”.
- 后续去各个科室进⾏检查, 诊断, 开药等操作, 都不必再出⽰⾝份证了, 只要凭就诊卡即可识别出当 前患者的⾝份.
- 看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的⾝份和就诊卡的关联就销毁了. (类 似于⽹站的注销操作)
- ⼜来看病, 可以办⼀张新的就诊卡, 此时就得到了⼀个新的 “令牌”
此时在服务器这边就需要记录"令牌"信息, 以及令牌对应的⽤⼾信息, 这个就是 Session 机制所做的⼯
作.
🍀理解Session
要理解Session,我们先来理解一下会话
在计算机领域, 会话是⼀个客⼾与服务器之间的不中断的请求响应. 对客⼾的每个请求,服务器能够识
别出请求来⾃于同⼀个客⼾. 当⼀个未知的客⼾向Web应⽤程序发送第⼀个请求时就开始了⼀个会话.
当客⼾明确结束会话或服务器在⼀个时限内没有接受到客⼾的任何请求时,会话就结束了.
⽐如我们打客服电话
每次打客服电话, 是⼀个会话. 挂断电话, 会话就结束了
下次再打客服电话, ⼜是⼀个新的会话.
如果我们⻓时间不说话, 没有新的请求, 会话也会结束
服务器同⼀时刻收到的请求是很多的. 服务器需要清楚的区分每个请求是从属于哪个⽤⼾, 也就是属于
哪个会话, 就需要在服务器这边记录每个会话以及与⽤⼾的信息的对应关系.
Session是服务器为了保存用户信息⽽创建的⼀个特殊的对象.
Session的本质就是⼀个 “哈希表”, 存储了⼀些键值对结构. Key 就是SessionID, Value 就是⽤⼾信息(用户信息可以根据需求灵活设计).
SessionId 是由服务器⽣成的⼀个 “唯⼀性字符串”, 从 Session 机制的⻆度来看, 这个唯⼀性字符串称
为 “SessionId”. 但是站在整个登录流程中看待, 也可以把这个唯⼀性字符串称为 “token”.
上述例⼦中的令牌ID, 就可以看做是SessionId, 只不过令牌除了ID之外, 还会带⼀些其他信息, ⽐如时间签名等。
- 当⽤⼾登陆的时候, 服务器在 Session 中新增⼀个新记录, 并把 sessionId返回给客⼾端. (通过
HTTP 响应中的 Set-Cookie 字段返回). - 客⼾端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId. (通过 HTTP 请求中的
Cookie 字段带上). - 服务器收到请求之后, 根据请求中的 sessionId在 Session 信息中获取到对应的⽤⼾信息, 再进⾏后
续操作.找不到则重新创建Session, 并把SessionID返回
Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失.
🌳Cookie 和 Session 的区别
- Cookie 是客⼾端保存⽤⼾信息的⼀种机制. Session 是服务器端保存⽤⼾信息的⼀种机制.
- Cookie 和 Session之间主要是通过 SessionId 关联起来的, SessionId 是 Cookie 和 Session 之间的桥梁
- Cookie 和 Session 经常会在⼀起配合使⽤. 但是不是必须配合.
- 完全可以⽤ Cookie 来保存⼀些数据在客⼾端. 这些数据不⼀定是⽤⼾⾝份信息, 也不⼀定是 SessionId
- Session 中的sessionId 也不需要⾮得通过 Cookie/Set-Cookie 传递, ⽐如通过URL传递.
🌲获取Cookie
🌸传统获取Cookie
@RequestMapping("/m10")
public String method10(HttpServletRequest request,HttpServletResponse response)
{
// 获取所有 cookie 信息
Cookie[] cookies = request.getCookies();
//打印Cookie信息
StringBuilder builder = new StringBuilder();
if (cookies!=null){
for (Cookie ck:cookies) {
builder.append(ck.getName()+":"+ck.getValue());
}
}
return "Cookie信息:"+builder;
}
Spring MVC是基于 Servlet API 构建的原始 Web 框架, 也是在Servlet的基础上实现的
HttpServletRequest , HttpServletResponse 是Servlet提供的两个类, 是Spring MVC⽅法的内置对象. 需要时直接在⽅法中添加声明即可.
- HttpServletRequest 对象代表客⼾端的请求, 当客⼾端通过HTTP协议访问服务器时,HTTP请
求头中的所有信息都封装在这个对象中,通过这个对象提供的⽅法,可以获得客⼾端请求的所有信
息. - HttpServletResponse 对象代表服务器的响应. HTTP响应的信息都在这个对象中, ⽐如向客⼾
端发送的数据, 响应头, 状态码等. 通过这个对象提供的⽅法, 可以获得服务器响应的所有内容
Spring MVC在这两个对象的基础上进⾏了封装, 给我们提供更加简单的使⽤⽅法.
🌸简洁获取Cookie
@RequestMapping("/getCookie")
public String cookie(@CookieValue("bite") String bite) {
return "bite:" + bite;
}
注意:
- 这个虽然获取更简单,但是一次只能获取你想要获取的参数,不能获取全部参数
🌴获取Session
Session是服务器端的机制,我们需要先存储,才能再获取
Session 也是基于HttpServletRequest来存储和获取的
🌸Session存储
@RequestMapping("/setSess")
public String setsess(HttpServletRequest request) {
// 获取Session对象
HttpSession session = request.getSession();
if (session != null) {
session.setAttribute("username", "java");
}
return "session 存储成功";
}
这个代码中看不到 SessionId 这样的概念的. getSession 操作内部提取到请求中的Cookie⾥的 SessionId, 然后根据SessionId获取到对应的Session 对象 Session 对象⽤HttpSession来描述
获取Session有两种⽅式
HttpSession getSession(boolean create);
HttpSession getSession();
HttpSession getSession(boolean create) :
- 参数如果为 true, 则当不存在会话时新建会话;
- 参数如果为 false, 则当不存在会话时返回 null
HttpSession getSession(): 和getSession(true) 含义⼀样, 默认值为true.
void setAttribute(String name, Object value): 使⽤指定的名称绑定⼀个对象到该 session 会话
🌸Session读取
🌻传统读取Session
读取 Session 可以使⽤传统的 HttpServletRequest
@RequestMapping("/test15")
public String test15(HttpServletRequest request) {
// 如果 session 不存在, 不会⾃动创建
HttpSession session = request.getSession(false);
String username = null;
if (session != null && session.getAttribute("username") != null) {
username = (String) session.getAttribute("username");
}
return "username:" + username;
}
🌻简洁获取Session
@RequestMapping("/test16")
public String test16(@SessionAttribute(value = "username",required = false) String username){
return "username:"+username;
}
⭕总结
感谢大家的阅读,希望得到大家的批评指正,和大家一起进步,与君共勉!