1 cookie和session的由来(小太爷自己的理解)
web服务器采用http协议,http本身是无状态的,但是实际应用场景要求web服务器是有状态的。于是cookie和session就是为了让基于http的web服务器变成有状态的。
这里说明一点,低一层的协议是否具有状态与高一层的应用是否具有状态有毛关系。举例说明:ip没有状态,tcp有状态,http无状态,然而基于http的web应用状态则可有可无。上回看到有个哥写的话很有道理:web应用=http协议 + cookie和session等状态机制 + 其它机制。这哥总结出这个简直天人啊!
2 cookie和session工作机制
有个哥说:cookie和session都不是在标准的http中定义的。但是绝大多数的web容器为了更好支持实践,都是支持session的。上回看shiro中也提到,shrio会代替tomcat做一个session的管理。所以由此可见,tomcat本身具有管理session的功能,我们的web应用是建立在tomcat的session管理机制上的。
由客户端(包括浏览器,或者自己写的爬虫等)保存cookie。即把cookie从响应中取出,保存到本地即可(本地:内存、磁盘都OK)。
由服务端保存session。tomcat估计就把session保存在自己占用的内存里。
再说一点,cookie无论是请求和响应,都是放到Header中的
贴服务端代码
@Controller
@RequestMapping("/spider")
class Resource{
@ResponseBody
@RequestMapping("/acountNum")
public ResponseEntity accountNum(HttpServletRequest httpServletRequest) {
HttpSession httpSession = httpServletRequest.getSession();
logger.info("sessionId:" + httpSession.getId());
HttpHeaders httpHeaders = new HttpHeaders();
Cookie[] cookies = httpServletRequest.getCookies();
if(cookies != null && cookies.length > 0){
for(Cookie cookie : cookies){
logger.info("cookieName:" + cookie.getName() + "cookieValue:" + cookie.getValue());
httpHeaders.add("Set-Cookie", "JSESSIONID="+ cookie.getValue() + “xiaotaiye”);// cookie写到Header中
}
}
JSONObject json = new JSONObject();
json.put("code","seccuss");
return new ResponseEntity(json,httpHeaders,HttpStatus.OK);
}
}
在浏览器发出请求 http://127.0.0.1:8080/spider/acountNum
第一请求进来,后台session是可以拿到的,且sessionId=37565EA81DDFFF70614BB130B72BFD3E
而cookies是拿不到的。
尽管第一次请求头没有cookie,但是第一次的响应头却有了cookie,且cookie取的是sessionId值。如下图(注意这个cookie是以前截图,cookie是以前的哈!!!):
做第二次请求http://127.0.0.1:8080/spider/acountNum
第二次请求时,请求头就有cookie了,后台也就可以拿到cookie了。后台显示设置cookie的方法我们也是给出了,即在header中添加Set-Cookie即可
扩展:
除了浏览器可以自动的将本地的cookie(如果存在)放到http的请求头中发出,代码同样可以实现例如:
CloseableHttpClient client = HttpClients.custom().setDefaultCookieStore(get保存到本地的cookieStore()).build(); 那么resteasy的这个client发出的http请求就是带cookie的
原生的postman也是会保存cookie的(只要服务端返回了cookie),只不过postman中看不到,必须用专门postman的cookie插件,才能让postman中看到保存的cookie。
总结:
cookie和session是为了解决web服务的状态而增加。客户端第一次请求进来,tomcat会产生一个对应的session,但是没有cookie,服务端会默认把sessionId作为cookie写到响应头中,返回给客户端。客户端第二次请求把这个cookie带上,那么就是实现了服务端的有状态。
如果我们想实现web服务端的无状态,两种思路很简单:
(1)方法1任你服务端给不给我返回cookie,反正我请求就是不带cookie给服务端,自然就成了无状态的了。因为只有客户端携带了cookie服务端才能找到对应的session。
(2)服务端spring mvc框架的处理器中调用 httpServletRequest.getSession(false)或者不要调用 httpServletRequest.getSession()方法,那么返回响应时不会给响应头写入cookie,自然也就成了无状态