目录
一、获取Cookie/Session
1、理解Cookie
HTTP 协议自身是属于 "无状态" 协议.
"无状态" 的含义指的是:默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系.
但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了。
上述图中的 "令牌" 通常就存储在 Cookie 字段中。
对于“令牌”,我们可以举一个医院的例子:
比如去医院挂号 :
- 看病之前先挂号. 挂号时候需要提供身份证号, 同时得到了⼀张 "就诊卡", 这个就诊卡就相当于患者的 "令牌".
- 后续去各个科室进行检查, 诊断, 开药等操作, 都不必再出示身份证了, 只要凭就诊卡即可识别出当前患者的身份.
- 看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的身份和就诊卡的关联就销毁了. (类似于网站的注销操作)
- 又来看病, 可以办⼀张新的就诊卡, 此时就得到了⼀个新的 "令牌" 。
此时在服务器这边就需要记录"令牌"信息, 以及令牌对应的用户信息, 这个就是 Session 机制所做的工作.
2、理解Session
我们先来了解⼀下什么是会话。会话: 对话的意思。
在计算机领域, 会话是⼀个客户与服务器之间的不中断的请求响应。
对客户的每个请求,服务器能够识 别出请求来自于同⼀个客户.
当⼀个未知的客户向Web应用程序发送第⼀个请求时就开始了⼀个会话.
当客户明确结束会话或服务器在⼀个时限内没有接受到客户的任何请求时,会话就结束了。
服务器同⼀时刻收到的请求是很多的. 服务器需要清楚的区分每个请求是从属于哪个用户, 也就是属于哪个会话, 就需要在服务器这边记录每个会话以及与用户的信息的对应关系.
Session是服务器为了保存用户信息而创建的⼀个特殊的对象.
Session的本质就是⼀个 "哈希表", 存储了⼀些键值对结构.
Key 就是SessionID, Value 就是用户信息。
SessionId 是由服务器生成的⼀个 "唯⼀性字符串", 从 Session 机制的角度来看, 这个唯⼀性字符串称为 "SessionId". 但是站在整个登录流程中看待, 也可以把这个唯⼀性字符串称为 "token".上述例子中的令牌ID, 就可以看做是SessionId, 只不过令牌除了ID之外, 还会带⼀些其他信息,比如时间, 签名等。
可以用下图来理解:
客户端访问服务器,观察cookie 和 session:
1、当用户登陆的时候, 服务器在 Session 中新增⼀个新记录, 并把 sessionId返回给客户端. (通过
HTTP 响应中的 Set-Cookie 字段返回).
2、 客户端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId . (通过 HTTP 请求中的
Cookie 字段带上).
3、 服务器收到请求之后, 根据请求中的 sessionId在 Session 信息中获取到对应的用户信息, 再进行后续操作;找不到则重新创建Session, 并把SessionID返回。
Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失.
3、Cookie 和 Session 的区别
1、Cookie 是 客户端保存用户信息 的⼀种机制. Session 是 服务器端保存用户信息 的⼀种机制.
2、Cookie 和 Session之间主要是通过 SessionId 关联起来的, SessionId 是 Cookie 和 Session 之间的桥梁。
3、Cookie 和 Session 经常会在⼀起配合使用. 但是不是必须配合 .
- 完全可以用 Cookie 来保存⼀些数据在客户端. 这些数据不一定是用户身份信息, 也不⼀定是 SessionId。
- Session 中的sessionId 也不需要非得通过 Cookie/Set-Cookie 传递, 比如通过URL传递。
4、获取Cookie
4.1 传统获取Cookie
代码:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/param")
public class ParamController {
@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响应的信息都在这个对象中, 比如向客户 端发送的数据, 响应头, 状态码等. 通过这个对象提供的方法, 可以获得服务器响应的所有内容。
此时没有设置Cookie, 通过浏览器访问: http://127.0.0.1:8080/param/m10 ,得到Cookie为null。
我们设置⼀下Cookie的值:
再次访问:
从这个例子中, 也可以看出Cookie是可以伪造的, 也就是不安全的, 所以使用Cookie时, 后端需要进行Cookie校验。
4.2 简洁获取Cookie
代码:
@RequestMapping("/getCookie")
public String cookie(@CookieValue("bite") String bite) {
return "bite:" + bite;
}
这种通过注解的方式获取cookie的前提是,已经设置好了cookie或者已经存在cookie了。
访问: http://127.0.0.1:8080/param/getCookie
结果:
5、Session 存储和获取
Session是服务器端的机制, 我们需要先存储 session, 才能获取 session.
Session 也是基于HttpServletRequest 来存储和获取的。
5.1 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 会话。
5.2 Session读取
读取 Session 可以使用 HttpServletRequest。
代码:
@RequestMapping("/getSess")
public String sess(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;
}
Object getAttribute(String name): 返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null.
我们来运行一下存储session和读取session的代码:
先设置Session: http://127.0.0.1:8080/param/setSess
通过Fiddler观察Http请求和响应情况:
可以看到, Http响应中, 通过Set-Cookie告知客户端, 把SessionID存储在Cookie中。
通过浏览器, 可以观察到运行结果:
获取Session: http://127.0.0.1:8080/param/getSess
我们通过Fiddler观察Http请求和响应:
可见,客户端向服务器发出请求时,会带上cookie. (Http请求时, 把SessionId通过Cookie传递到了服务器)
5.3 简洁获取 Session
方法一:
代码如下:
@RequestMapping("/getSess2")
public String sess2(@SessionAttribute(value = "username",required = false)String username) {
return "username:"+username;
}
运行结果: http://127.0.0.1:8080/param/getSess2
方法二:通过Spring MVC内置对象HttpSession 来获取
@RequestMapping("/getSess3")
public String sess3(HttpSession session) {
String username = (String)session.getAttribute("username");
return "username:"+username;
}
HttpSession session = request.getSession();Session 不存在的话, 会自动进行创建
运行结果: http://127.0.0.1:8080/param/getSess3
对于cookie 和 session 的内容就先介绍到这里了,希望能给你们带来帮助呀!