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>5</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

相关文章