zoukankan      html  css  js  c++  java
  • HttpSession implements session

    体验

      使用HttpSession进行会话管理,完全可以忽略HTTP无状态的事实。


    HttpSession会话管理原理

      使用HttpSession进行会话管理十分方便,让Web应用程序看似可以“记得”浏览器发出的请求,连接数个请求间的关系。但无论如何,Web应用程序基于HTTP协议的事实并没有改变。这背后Web容器帮我们做了一些工作。
      当第一次调用HttpServletRequest的getSession()时,Web容器会创建一个HttpSession对象,每个HttpSession对象都有个特殊的ID,这个Session ID默认会使用Cookie存放在浏览器中。当浏览器再次请求应用程序时,会将Cookie中存放的Session ID一并发送给应用程序,Web容器就能根据Session ID来找出对应的HttpSession对象,这样就可以取得各个浏览器的会话数据。


    存储Session ID的cookie

      存储Session ID的Cookie “默认”为关闭浏览器就失效,所以重启浏览器请求应用程序时,通过getSession()取得的是新的HttpSession对象。注意默认关闭浏览器马上失效的是浏览器上的Cookie,而不是HttpSession。因为Cookie失效了,就无法通过Cookie来发送Session ID,所以使用getSession()时,容器会产生新的HttpSession。


    HttpSession

      要让HttpSession立即失效必须运行invalidate()方法,否则的话,HttpSession会等到设定的失效期间过后才会被容器销毁回收。
      可以执行HttpSession的setMaxInactiveInterval()方法,设定浏览器多久没有请求应用程序,HttpSession就自动失效,单位是“秒”。也可以在web.xml中设定HttpSession默认的失效时间,单位是“分钟”


    新接口

      在Servlet 3.0中新增了SessionCookieConfig接口,可以通过ServletContext的getSessionCookieConfig()来取得实现该接口的对象,通过该对象可以设定存储Session ID的Cookie的相关信息,例如可以通过setName()将默认的名称(在Tomcat中,Cookie的默认名称是JSESSIONID)修改为别的名称,通过setAge()设定存储Session ID的Cookie存活期限等,单位是“秒”。
      但是注意,设定SessionCookieConfig必须在ServletContext初始化之前,所以实际上修改存储Session ID的Cookie存活期限等信息时有两种方法:
      1、在web.xml中设定
      2、实现ServletContextListener,容器在初始化ServletContext时会调用ServletContextListener的contextInitialized()方法,可以在其中取得ServletContext进行SessionCookieConfig设定。


    占用内存

      HttpSession对象会占用服务器内存空间,所以HttpSession中尽量不要存储耗资源的大型对象,必要时将属性移除,或者不需使用HttpSession时,执行invalidate()让HttpSession失效。


    线程安全
      HttpSession并非线程安全,所以必须注意属性设定时共享存取的问题。


    example

    package com.test;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    @WebServlet("/questionnaire")
    public class Questionnaire extends HttpServlet {
        protected void processRequest(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            request.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
    
            PrintWriter out = response.getWriter();
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<meta charset='UTF-8'>");
           out.println("<title>问卷调查</title>");
            out.println("</head>");
            out.println("<body>");
    
            String page = request.getParameter("page");
            out.println("<form action='questionnaire' method='get'>");
    
            if(page == null) {          // 第一頁問卷
                out.println("問題一:<input type='text' name='p1q1'><br>");
                out.println("問題二:<input type='text' name='p1q2'><br>");
                out.println("<input type='submit' name='page' value='page2'>");
            }
            else if("page2".equals(page)) {    // 第二頁問卷
                HttpSession session = request.getSession();
                session.setAttribute("p1q1", request.getParameter("p1q1"));
                session.setAttribute("p1q2", request.getParameter("p1q2"));
                //session.invalidate(); // 销毁session
                out.println("問題三:<input type='text' name='p2q1'><br>");
                out.println("<input type='submit' name='page' value='finish'>");
            }
            else if("finish".equals(page)) {    // 最後答案收集
                HttpSession session = request.getSession();
                out.println(session.getAttribute("p1q1") + "<br>");
                out.println(session.getAttribute("p1q2") + "<br>");
                out.println(request.getParameter("p2q1") + "<br>");
            }
            out.println("</form>");
            out.println("</body>");
            out.println("</html>");
            out.close();
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            processRequest(request, response);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            processRequest(request, response);
        }
    }
    View Code
    
    
    <?xml version="1.1" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
             version="3.0">
      <display-name>Archetype Created Web Application</display-name>
    
      <session-config>
        <session-timeout>30</session-timeout>
        <cookie-config>
          <name>my-session-id</name>
          <!-- js 无法读取cookie -->
          <http-only>true</http-only>
          <!-- 单位是秒 -->
          <!--<max-age>50</max-age>-->
        </cookie-config>
      </session-config>
    
    </web-app>
    View Code
    测试方法:
    1、测试关闭浏览器cookie失效,原来的session对象无法找到
        (1)访问:http://127.0.0.1:8000/questionnaire
        (2)填写表单并提交,提交后服务器端会往session写入数据
        (3)关闭浏览器
        (4)访问:http://127.0.0.1:8000/questionnaire?p2q1=123&page=finish
    2、SessionCookieConfig测试
        查看web.xml
  • 相关阅读:
    19 C#循环语句的跳过和中断 continue和break
    18 C#中的循环执行 for循环
    一种绝对提高开发水平的方法(推荐英语)
    大数据知识普及
    全链路压测压测报告
    QuickSearch快排
    二分查找
    算法
    基于领域驱动设计的业务中台架构设计
    【科普】Scrum——从橄榄球争球到敏捷开发
  • 原文地址:https://www.cnblogs.com/Mike_Chang/p/10054390.html
Copyright © 2011-2022 走看看