cookie和session的思考

来源:互联网 发布:广东省网络医院待遇 编辑:程序博客网 时间:2024/06/06 21:06

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,自然也就成了无状态


原创粉丝点击