• Session原理,生命周期


    在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据(保存该浏览器(会话)的相关信息)时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。

    Session和Cookie的主要区别在于:

    • Cookie是把用户的数据写给用户的浏览器。
    • Session技术把用户的数据写到用户独占的session中(服务器端)。
    • Cookie由于存在客户端,存在安全问题,每次使用cookie都会在本地生成一个cookie文件
      Session将数据存在服务器端,数据更加安全
    • Session将数据保存在服务器端,占用服务器资源,Cookie不会占用服务器的资源

    Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。

    例如:京东购物车信息保存Cookie 、淘宝购物车信息保存Session

    session对象:创建

    HttpSession httpsession = request.getSession();

    存储session

    httpsession.setAttribute(name,object);

    对于上述图例的实现,用IE6保存session数据,当前浏览器可以获得,但是第二个IE6 无法获得第一个浏览器保存Session 数据,IE8以上 或 火狐浏览器:当打开多个浏览器窗口,之间Session共享

    原因:IE6 cookie 中保存jsessionId 默认会话级别 ;IE8或者火狐 保存cookie中 jsessionId 默认持久cookie

    (一)Session实现原理

    因此,若果将session id 持久化 ,IE6也可以实现上述功能。其中的Session Id 可以通过Session.getId()方法获得(Session保存数据依赖于cookie来进行实现)。

    将写回给 浏览器 JSESSIONID 持久化(手动)

    
            Cookie cookie = new Cookie("JSESSIONID",httpSession.getId());
            cookie.setMaxAge(60 * 60);
            cookie.setPath("/history");
            response.addCookie(cookie);

    因此,一般我们不允许用户禁用cookie,如果意外遇到这种情况可以:

    禁用cookie解决方案

    解决办法:URL重写
    第二次访问服务器会带一个URL,由于不能通过cookie方式传递SessionId,所以需要在URL中携带SessionId,例如:

    http://localhost:8080/shopping/readsession;jsessionid=xxx

    注意:携带SessionId信息是使用分号“;”而不是问号“?”

    因此在writesession中添加如下即可:

        String url = "/shopping/readsession";
        // 对url 进行重写 拼接 jsessionid
        url = response.encodeURL(url);
        response.getWriter().println("<a href='" + url + "'>查看保存内容</a>");

    问题1:如果客户端关闭浏览器,是否就删除了Session ?
    没有,Session保存在服务器端

    问题2:IE6 保存Session,关闭浏览器,再次打开,数据丢失了?
    IE6默认jsessionId保存会话Cookie中,关闭浏览器,会话cookie就会被删除,客户端丢失jsessionid 无法找到服务器对应Session对象

    • 服务器Session对象还存在

    (二)生命周期
    Cookie生命周期

    • 创建 Cookie cookie = new Cookie(); response.addCookie();
    • 销毁 会话cookie会在浏览器关闭时销毁,持久cookie在cookie过期(MaxAge)后销毁

    Session生命周期

      创建:

      HttpSession httpsession = request.getSession();创建session

      销毁 (例如,销毁session即清空了购物车)

      (1)服务器关闭时销毁 

      (2) 手动调用session.invalidate (可以设置一个按钮(href实现),点击实现购物车的清空)

      request.getSession.invalidate();
      response.sendRedirect("shopping/session/demo/cart.jsp");//重定向回购物车界面

      (3)Session过期时销毁,设置session过期的方法: 

    1、配置web.xml

    <!--配置session有效时间,单位是分钟,以下表示连续30分钟不使用即销毁-->
    <session-config>
        <session-timeout>30<session-timeout>
    </session-config>

    2、调用session对象 setMaxInactiveInterval(int interval) 单位是秒

    HttpSession session = request.getSession();
    session.setMaxInactiveInterval(60*60); //设置session过期时间1小时 

    (三)Session的应用举例
    Session的一个常见应用就是购物车功能的实现:

    public class BuyServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 1、获得购买商品编号
            String id = request.getParameter("id");
    
            // 2、根据编号 得到商品名称,实际工程是进行数据库查询
            String[] arr = { "冰箱", "洗衣机", "热水器", "微波炉", "空调", "电饭锅" };
            String productName = arr[Integer.parseInt(id) - 1];
    
            // 3、判断商品名称是否在购物车中
            /**
            *判断购物车是否存在,购物车对象在Session中,因此购物车应该从
            *Session中获得,通过购物车的名字,假设名字为“cart”
            */
            Map<String, Integer> cart = (Map<String, Integer>) request.getSession()
                    .getAttribute("cart"); // 可能返回 null
            if (cart == null) {
                // 购物车对象不存在
                cart = new HashMap<String, Integer>();
            }
                //商品名称为key
            if (cart.containsKey(productName)) {
                // 购物车存在该商品 数量+1
                int number = cart.get(productName);
                cart.put(productName, number + 1);
            } else {
                // 商品没有在购物车中
                cart.put(productName, 1);
            }
    
            // 将购物车加入session
            request.getSession().setAttribute("cart", cart);
    
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().println("商品已经被加入购物车!");
    
            response.getWriter().println(
                    "<a href='/shopping/session/demo/cart.jsp'>查看购物车</a>");
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
  • 相关阅读:
    用mescroll实现无限上拉增加数据,下拉刷新数据 (学习笔记)
    jackson使用问题:mapper.readValue()将JSON字符串转反序列化为对象失败或异常
    常用 NHibernate.Criterion
    Threading
    并口
    电子称 弹钱箱脉冲
    ZIP文件解压
    wpf 异步加载 只需6段代码
    Newtonsoft.Json使用
    接口post +json +bean
  • 原文地址:https://www.cnblogs.com/albertzhangyu/p/8950985.html
Copyright © 2020-2023  润新知