前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java--Session与Cookie

Java--Session与Cookie

作者头像
SuperHeroes
发布2018-05-22 16:20:46
6060
发布2018-05-22 16:20:46
举报
文章被收录于专栏:云霄雨霁云霄雨霁

Session与Cookie的作用都是为了保持访问用户与后端服务器的交互状态。它们各有优缺点。

Cookie:

Cookie的作用通俗地讲就是当一个用户通过HTTP访问一个服务器时,这个服务器会将一些键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器时,数据又被完整地带回给服务器。

由于HTTP是一种无状态的协议,当用户第一次访问请求结束后,后端服务器就无法知道下一次访问的是不是同一用户。Cookie作用正是解决这个问题的。

Cookie现在有两个版本,Version 0和Version 1。两个版本的属性项有区别,可以查看相关文档。

服务端创建Cookie:

服务端可以像下面这样创建Cookie:

代码语言:javascript
复制
String getCookie(Cookie[] cookies, String key){
    if(cookies!=null)
        for(Cookie cookie:cookies)
            if(cookie.getName().equals(key))
                return cookie.getValue();
    return null;
}

@Override
public void doGet(HttpServletRequest request,HttpServletResponse response)
        throws IOExpection,ServletException{
    Cookie[] cookies = request.getCookies();
    String userNmae = getCookie(cookies,"userName");
    String userAge = getCookie(cookies,"userAge");
    if(userName == null)
        response.addCookie(new Cookie("userName","Dabao"));
    if(userAge == null)
        response.addCookie(new Cookie("userAge ","20"));
    response.getHeaders("Set-Cookie");
}

Cookie创建好之后,如何把它加到HTTP的Header中传给客户端?以Tomcat为例,调用generateCookieString方法将Cookie对象构造成一个字符串,构造的字符串形式如:userName="Dabao"。然后将这个字符串命名为Set-Cookie添加到MimeHeaders中。

正如上面的代码,当我们调用addCookie方法创建多个Cookie时,这些Cookie最终是在一个Header项中还是每个作为一个独立的Header项?答案是后者。每次调用addCookie时,都会创建一个Header。那么在返回给客户端浏览器时构造HTTP响应头的时候这些Header会合并吗?答案是不会。看一下Tomcat构造Http响应头的代码就明白了:

代码语言:javascript
复制
int size = headers.size();
for(int i=0;i<size;i++){
    outputBuffer.sendHeader(headers.getName(i),headers.getValue(i));
}
从客户端获取Cookie:

当我们请求某个URL时,浏览器会根据这个URL路径将符合条件的Cookie放在Request请求头中传回给服务器端,服务器根据request.getCookies()来获取所有的Cookies。

Session:

Cookie可以让服务端跟踪每个客户端的访问,但每次访问客户端都要将Cookie传回服务端,如果Cookie很多,就增加了传输量,而Session就是为了解决这个问题出现的。

同一个客户端每次和服务端交互时,不需要每次都传回所有的Cookie,而只需要传回一个ID,这个ID是客户端第一次访问服务端生成的,而且每个客户端是唯一的。这样每次访问服务端就只需要传回ID就可以了。

有了Session ID,服务端就可以创建HttpSession对象了。第一次出发通过request.getSession()方法,如果当前ID没有相应的HttpSession对象,就创建新对象并加入到org.apache.catalina.Manager的sessions容器中保存。Manager类将管理所有的Session的生命周期,只要HttpSession对象存在,用户就可以根据Session ID来获取这个对象。

持久化Session:  当Servlet容器重启或关闭时,Standard负责持久化没有过期的StandardSession对象,它会将所有StandardSession对象持久化到一个以“SESSIONS.ser”为文件名的文件中。到Servlet重启时,也就是StandardManager初始化时,它会重新读取这个文件,解析出所有Session对象,重新保存在StandardManager的sessions集合中。注意:当Servlet容器关闭时,StandardManager类会调用unload方法持久化对象,所以Servlet必须是通过stop方法关闭的,而不是直接结束(kill)Servlet容器的进程,否则不发持久化。

Session肯定不是永久存储在服务器端的,每个session都有一个有效时间,超过有效时间就会被清除。检查每个Session是否失效是在Tomcat的一个后台线程中进行的。

除了后台线程检查失效外,调用request.getSession()时也会检查该Session是否还有效。值得注意的是,request.getSession()方法调用的Session永远会存在,因为如果之前的失效了就会创建一个新的。但以前设置的Session值将会丢失。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Cookie:
    • 服务端创建Cookie:
      • 从客户端获取Cookie:
      • Session:
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档