前言:
了解过SpringMVC的开发结构之后,接下来进一步学习和了解用户(浏览器)和服务器的交互过程
在了解用户和服务器的交互过程之前,需要先理解什么是Cookie,什么是Session,只有理解这两者的概念才能更好地体会交互过程。
Cookie
概念:Cookie本身是一种小型文本数据,用来记录用户的行为,实现个性化交互以及识别用户。
很多时候会把Cookie和缓存的定义给混淆,但是二者之间差别很大!
带入场景来进行理解:
你访问一个购物网页进行购物操作,在首次访问购物网页的时候需要对网页的静态资源进行下载,例如css,js以及html这些静态资源会被下载在对应的路径里,这就是缓存。
下载之后的静态资源会放在缓存里,在第二次访问网页就不需要再次加载这些静态资源,这些资源不会因为浏览器关闭就过期,除非把缓存里的内容过期或者被删除掉,后续第二次访问才需要进行下载。
访问购物网页进行登录,或者访问购物网页的一些行为(例如搜索对应的商品),开发者为了能够给客户更好的体验就会在服务器里记录下这些状态或者对应的行为,然后将这些记录整合成一个小型文本数据保留在浏览器中,后续使用浏览器访问的时候,浏览器会携带Cookie信息向服务器搜索会话数据
也就是说,缓存是加载页面的静态资源,而Cookie好比一段小型文本数据记录用户的行为、状态,二次访问网页发起会话请求就会携带这段文本数据去服务器里搜索对应的会话数据,获取会话服务
Session
通过了解上述内容我们能理解Cookie是客户端用来存储用户信息的小型文本数据,在了解Session以前得先理解一个概念——会话。
什么是会话?在计算机领域,会话是指客户和服务器之间的不间断请求响应。由客户端向服务器发送请求,服务器接收请求进行计算并返回响应,这就是一个完整的会话过程,而会话过程终止于客户端明确表示结束会话或者会话超过时间限制。
简言之,Session是服务器用来保存用户信息的对象。服务器会记录下用户的信息,而存储用户的信息的过程中会对用户信息进行标识,以便后续调用会话匹配对应的请求,这个标识SessionId。
Cookie和Session配合使用
例如:学生卡——校园门禁
学生卡刷卡之后会向门禁系统服务器发送请求,请求中携带了学生的信息,而此时服务器接收到请求就根据请求中携带的学生信息进行匹配,查看服务器中是否存在匹配的信息,匹配就通过,不匹配就不通过。
在这个例子中,学生卡作为学生信息的载体,扮演的就是Cookie的角色,而服务器里存储的用来进行身份匹配的学生信息,扮演的则是Session的角色,学号作为sessionId,学生卡里存储的学号到服务器中进行学号匹配进一步进行身份匹配
Session的本质是一个“哈希表”,通过key去服务器里匹配对应的value,key是SessionId,value是与sessionId进行匹配的用户数据。
注意:Cookie和Session经常搭配使用,但二者不是必须捆绑使用。可以单独用Cookie作为文本数据,这些数据不一定要有sessionId,Session中的sessionId不一定是通过Cookie进行传递也可以是用url拼接或构造请求体进行传递
Cookie和Session的存储和获取
Cookie的存储
1.服务器生成并发送Cookie指令——客户端向服务器发送请求,服务器计算响应之后若需要在客户端存储Cookie会在返回的响应中添加Set-Cookie字段,字段中会包含Cookie信息
2.浏览器自动进行解析以及保存Cookie信息——浏览器会自动解析服务器返回的响应,如果存在Set-Cookie字段就会自动保存Cookie
Session的存储
Session的存储始于客户端向服务器发送请求,服务器判断当前请求无对应的Session,由此触发Session创建的逻辑,大致分为三步走——生成sessionId,创建Session容器,将sessionId传递给客户端
生成sessionId:服务器通过随机算法生产一个字符串,作为客户端的Session标识
创建Session容器:在服务器存储的地方,构造一个与sessionId绑定的数据容器
传递sessionId给客户端:在返回的响应添加Set-Cookie字段,将sessionId作为Cookie传递给客户端进行存储
Session以及Cookie的获取
由于Spring是基于HttpServlet API为构建,所以在进行存储和获取我们是基于HttpServletRequest以及HttpServletResponse来获取
//使用session进行存储
@RequestMapping("/setsess")
public String setsess(HttpServletRequest request)
{
//获取session对象
HttpSession session = request.getSession();
if(session != null)
{
//对应构造的响应里的key-value
session.setAttribute("user","java")
}
return "session构造成功";
}
获取session
//获取session
@RequestMapping("/getsess")
public String setsess(HttpServletRequest request)
{
//如果session不存在,是不会自动创建的
HttpSession session = request.getSession(false);
String username = null;
if(session != null && session.getAttribute("username")!=null)
{
//
username = session.getAttribute("username");
}
return "username"+username;
}
简洁获取——使用SpringMVC内置对象HttpSession来获取
//获取session
@RequestMapping("/getsess")
public String setsess(HttpSession session)
{
String username = (String)session.getAttribute("username");
return "username"+username;
}
获取Header
获取Header也是通过HttpServletRequest来获取
@RequestMapping("param")
public String param(HttpServletRequest request,HttpServletResponse response)
{
String UserAgent = request.getHeader("User-Agent");
return UserAgent;
}
简洁获取Header——使用@RequestHeader注解获取
@RequestMapping("param")
public String param(@RequestHeader("User-Agent")String UserAgent)
{
return UserAgent;
}
以上的代码我们学会了如何设置响应数据,而响应可以返回的不单单可以是数据,还有静态页面,状态码,Header信息等