JAVA语言之JavaWeb的session及其共享技术
小标 2019-02-28 来源 : 阅读 871 评论 0

摘要:本文主要向大家介绍了JAVA语言之JavaWeb的session及其共享技术,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言之JavaWeb的session及其共享技术,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

JAVA语言之JavaWeb的session及其共享技术

1.什么叫会话


   一次会话指的是:就好比打电话,A给B打电话,接通之后,会话开始,直到挂断电话,该次会话就结束了,而浏览器访问服务器,就跟打电话一样,浏览器A给服务器发送请求,访问web程序,该次会话就已经接通,其中不管浏览器发送多少请求(就相当于接通电话后说话一样),都视为一次会话,直到浏览器关闭,本次会话结束。


   其中注意,一个浏览器就相当于一部电话,如果使用火狐浏览器,访问服务器,就是一次会话了,然后打开google浏览器,访问服务器,这是另一个会话,虽然是在同一台电脑,同一个用户在访问,但是,这是两次不同的会话。


2.引入cookie和session


   思考一个问题,一个浏览器访问一个服务器就能建立一个会话,如果别的电脑,都同时访问该服务器,就会创建很多会话,就拿一些购物网站来说,我们访问一个购物网站的服务器,会话就被创建了,然后就点击浏览商品,对感兴趣的商品就先加入购物车,等待一起付账,这看起来是很普通的操作,但是想一下,如果有很多别的电脑上的浏览器同时也在访问该购物网站的服务器,跟我们做类似的操作呢?服务器又是怎么记住用户,怎么知道用户A购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,不能放入用户B或用户C的购物车内的呢?


        这里我们就用cookie和session两种会话跟踪技术来跟踪整个会话。


3.cookie简介


3.1.cookie的工作原理


1)首先浏览器向服务器发出请求。


2)服务器就会根据需要生成一个Cookie对象,并且把数据保存在该对象内。


3)然后把该Cookie对象放在响应头,一并发送回浏览器。


4)浏览器接收服务器响应后,提出该Cookie保存在浏览器端。


5)当下一次浏览器再次访问那个服务器,就会把这个Cookie放在请求头内一并发给服务器。


6)  服务器从请求头提取出该Cookie,判别里面的数据,然后作出相应的动作。


3.2.cookie中的常用方法


Cookie cookie=new Cookie(String name,String value)        构造一个cookie对象 


response.addCookie(Cookie cookie)       是将一个cookie对象传入客户端。


request.getCookies()       得到所有的cookie对象


cookie.getName()            得到此cookie对象的名字


cookie.getValue()             得到对应名称的cookie的值


cookie.setMaxAge()         设置过期时间


3.3.案例


@WebServlet("/CookieServletDemo1")
public class CookieServletDemo1 extends HttpServlet {
  private static final long serialVersionUID = 1L;

  /**
     * @see HttpServlet#HttpServlet()
     */
  public CookieServletDemo1() {
    super();
    // TODO Auto-generated constructor stub
  }

  /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    // 创建cookie对象
    // cookie中`存放的数据以键值对存在map<String,String> 键和值都只能是字符串,不支持中文
    Cookie cookie = new Cookie("username", "zhangsan");
    Cookie cookie1 = new Cookie("password", "1234");
    // 失效时间 以秒为单位
    cookie.setMaxAge(60 * 60);
    response.addCookie(cookie);
    response.addCookie(cookie1);
  }

  /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }

}


@WebServlet("/CookieServletDemo2")
public class CookieServletDemo2 extends HttpServlet {
  private static final long serialVersionUID = 1L;

  /**
     * @see HttpServlet#HttpServlet()
     */
  public CookieServletDemo2() {
    super();
    // TODO Auto-generated constructor stub
  }

  /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //      从请求头中获取cookie信息
    Cookie[] cookies = request.getCookies();
    for(Cookie c:cookies){
      System.out.println(c.getName()+"===="+c.getValue());
    }
  }

  /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }

}


3.4.浏览器中查看cookie


不同的浏览器略有差别,这里以谷歌浏览器为例。


F12打开开发者工具 ---点击Application选项---选中其中的cookie---选择相应的站点---看到该站点中的所有cookie信息。


3.5.cookie的应用场景


   cookie的应用场景有很多,最具代表性的当属网站的记录用户账号和密码的功能了,大家可能经常看到登录某某论坛,某某网站时,下面有个选项为N天内自动登录,其实这就是cookie的应用。当用户第一次输入账号密码时给服务器发送请求时,服务器会根据账号密码回写一个字符串cookie,当用户下次再向该服务器发送登录请求时,则带着这个字符串cookie一起去访问服务器,这时,服务器只需要对比次字符串和数据库中存储的字符串是否相同,则可以达到用户自动登录功能。


3.6.cookie的局限性



  • Cookie数量和长度的限制。每个站点最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。


  • cookie中只能存字符串。且不支持中文


  • cookie不适合保存敏感数据(例如密码)可见的



4.session


4.1.session的工作原理


1)浏览器发出请求到服务器。


2)服务器会根据需求生成Session对象,并且给这个Session对象一个编号,一个编号对应一个Session对象


3)服务器把需要记录的数据封装到这个Session对象里,然后把这个Session对象保存下来。


4)服务器把这个Session对象的编号放到一个Cookie里,随着响应发送给浏览器


5)浏览器接收到这个cookie就会保存下来


6)当下一次浏览器再次请求该服务器服务,就会发送该Cookie


7)服务器得到这个Cookie,取出它的内容,它的内容就是一个Session的编号!!!


8)凭借这个Session编号找到对应的Session对象,然后利用该Session对象把保存的数据取出来!


4.2.session的常用方法

方法解释
void setAttribute(String attribute, Object value)设置Session属性。value参数可以为任何Java Object。通常为Java Bean。value信息不宜过大
String getAttribute(String attribute)返回Session属性
void removeAttribute(String attribute)移除Session属性
String getId()返回Session的ID。该ID由服务器自动创建,不会重复
long getCreationTime()返回Session的创建日期。
long getLastAccessedTime()返回Session的最后活跃时间。返回类型为long
int getMaxInactiveInterval()返回Session的超时时间。单位为秒。超过该时间没有访问,服务器认为该Session失效
void setMaxInactiveInterval(int second)设置Session的超时时间。单位为秒4.3.


4.3.案例


@WebServlet("/SeesionServletDemo1")
public class SeesionServletDemo1 extends HttpServlet {
  private static final long serialVersionUID = 1L;

  /**
     * @see HttpServlet#HttpServlet()
     */
  public SeesionServletDemo1() {
    super();
    // TODO Auto-generated constructor stub
  }

  /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    // 创建session对象
    HttpSession session = request.getSession();
    System.out.println(session.getId());

    session.setAttribute("name", "zhangsan");

    session.setAttribute("student", new Student(1, "zhangsan", 12));
    Student stu = (Student) session.getAttribute("student");

    stu.setName("lisi");

    // 设置过期时间 单位是秒
    //      session.setMaxInactiveInterval(2);
    // 直接销毁session  注销登录
    //      session.invalidate();

  }

  /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }

}


public class Student {

  private Integer id;
  private String name;
  private Integer age;
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Integer getAge() {
    return age;
  }
  public void setAge(Integer age) {
    this.age = age;
  }
  public Student(Integer id, String name, Integer age) {
    super();
    this.id = id;
    this.name = name;
    this.age = age;
  }
  public Student() {
    super();
    // TODO Auto-generated constructor stub
  }
}


@WebServlet("/SeesionServletDemo2")
public class SeesionServletDemo2 extends HttpServlet {
  private static final long serialVersionUID = 1L;

  /**
     * @see HttpServlet#HttpServlet()
     */
  public SeesionServletDemo2() {
    super();
    // TODO Auto-generated constructor stub
  }

  /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    // 创建session对象
    HttpSession session = request.getSession();

    System.out.println(session.getAttribute("name"));

    Student stu = (Student) session.getAttribute("student");
    System.out.println(stu.getName());

  }

  /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }

}


4.4.session的生命周期


session对象生命周期:



  • session对象什么创建? 


    • 执行request.getSession()方法时 



  • session对象什么销毁?


    • 默认情况下,session对象在30分钟之后服务器自动销毁。


    • 手动设置session有效时长


    • void setMaxInactiveInterval(int interval) -以秒为单位。


    • 手动销毁


    • void invalidate()




4.5.session在一次会话结束后消失的原因


   由于session的使用需要依赖cookie,cookie每次从浏览器端传输session的id到后台,然后查找对应编号的session进行使用,但由于此时的cookie默认的失效时间是一次会话,当一次会话结束后,存放id的cookie对象就消失了,下一次会话访问时就会生成新的id,那存储在原来的session对象中的数据就无法找到了。


4.6.浏览器禁用cookie能否使用session


可以,但需要手动拼接id传过去,例如


//localhost:8080/day06/session.jsp;jsessionid=AE62ECBAAD2CA16DA6AEBF1D1527CD45


jsessionid指的就是session对应的id


4.7.session共享


4.7.1.基于数据库的Session共享


首选当然是大名鼎鼎的Mysql数据库,并且建议使用内存表Heap,提高session操作的读写效率。这个方案的实用性比较强,相信大家普遍在使用,它的缺点在于session的并发读写能力取决于Mysql数据库的性能,同时需要自己实现session淘汰逻辑,以便定时从数据表中更新、删除 session记录,当并发过高时容易出现表锁,虽然我们可以选择行级锁的表引擎,但不得不否认使用数据库存储Session还是有些杀鸡用牛刀的架势。


4.7.2.基于Cookie的Session共享


   这个方案我们可能比较陌生,但它在大型网站中还是比较普遍被使用。原理是将全站用户的Session信息加密、序列化后以Cookie的方式, 统一种植在根域名下(如:.host.com),利用浏览器访问该根域名下的所有二级域名站点时,会传递与之域名对应的所有Cookie内容的特性,从而实现 用户的Cookie化Session 在多服务间的共享访问。


  这个方案的优点无需额外的服务器资源;缺点是由于受http协议头信心长度的限制,仅能够存储小部分的用户信息,同时Cookie化的 Session内容需要进行安全加解密(如:采用DES、RSA等进行明文加解密;再由MD5、SHA-1等算法进行防伪认证),另外它也会占用一定的带宽资源,因为浏览器会在请求当前域名下任何资源时将本地Cookie附加在http头中传递到服务器。


4.7.3.基于Memcache的Session共享


 Memcache由于是一款基于Libevent多路异步I/O技术的内存共享系统,简单的Key + Value数据存储模式使得代码逻辑小巧高效,因此在并发处理能力上占据了绝对优势,目前本人所经历的项目达到2000/秒 平均查询,并且服务器CPU消耗依然不到10%。


  另外值得一提的是Memcache的内存hash表所特有的Expires数据过期淘汰机制,正好和Session的过期机制不谋而合,降低了 过期Session数据删除的代码复杂度,对比“基于数据库的存储方案”,仅这块逻辑就给数据表产生巨大的查询压力。

   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程