会话管理

简介: 一、会话管理的基本原理  web应用程序的请求与响应是基于HTTP,为无状态的通信协议,服务器不会记得这次请求和下次请求的关系,如购物车,用户可能在多个购物网页之间采购商品,web应用程序必须有个方式来得知用户在这些网页中采购了哪些商品,这种记得此次请求与之后请求间关系的方式,就称为会话管理(Session Management).1、使用隐藏域  隐藏域就是主动告知服务器多次请求间必要信息的方式之一。

一、会话管理的基本原理

  web应用程序的请求与响应是基于HTTP,为无状态的通信协议,服务器不会记得这次请求和下次请求的关系,如购物车,用户可能在多个购物网页之间采购商品,web应用程序必须有个方式来得知用户在这些网页中采购了哪些商品,这种记得此次请求与之后请求间关系的方式,就称为会话管理(Session Management).

1、使用隐藏域

  隐藏域就是主动告知服务器多次请求间必要信息的方式之一。以问卷作答的为例,上一页的问卷答案,可以用隐藏域的方式放在下一页的窗体中,这样发送下一页窗体,就可以一并发送这些隐藏域,每一页的问卷答案就可以保留下来。上一次的结果如何成为下一页的隐藏域呢?做法之一就是将上一页的结果发送至服务器,由服务器将上一页结果以隐藏域的方式再响应给浏览器。

    

  例1:程序中有两页问卷,第一页的结果会在第二页成为隐藏域,当第二页发送时,就可以看到两页问卷的所有答案。

 1 package Session.Management;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 import java.io.UnsupportedEncodingException;
 6 
 7 import javax.servlet.ServletException;
 8 import javax.servlet.annotation.WebServlet;
 9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 import javax.servlet.http.HttpSession;
13 
14 /**
15  * Servlet implementation class Questionnaire
16  */
17 @WebServlet("/questionnaire")
18 public class Questionnaire extends HttpServlet {
19     private static final long serialVersionUID = 1L;
20        
21     /**
22      * @see HttpServlet#HttpServlet()
23      */
24     public Questionnaire() {
25         super();
26         // TODO Auto-generated constructor stub
27     }
28 
29     /**
30      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
31      */
32     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
33         // TODO Auto-generated method stub
34         processRequest(request,response);
35     }
36 
37     private void processRequest(HttpServletRequest request,
38             HttpServletResponse response) throws IOException {
39         // TODO Auto-generated method stub
40         request.setCharacterEncoding("UTF-8");
41         response.setContentType("text/html;charset=UTF-8");
42         PrintWriter out=response.getWriter();
43         out.println("<!DOCTYPE html>");
44         out.println("<html>");
45         out.println("<head>");
46         out.println("<meta content='text/html; charset=UTF-8' http-equiv='content-type'>");
47         out.println("<title>Questionnaire</title>");
48         out.println("</head>");
49         out.println("<body>");
50         String page=request.getParameter("page");//page请求参数决定哪一个页面问卷
51         out.println("<form action='questionnaire' method='post'>");
52         if(page==null){
53             out.println("问题一:<input type='text' name='p1q1'><br>");
54             out.println("问题二:<input type='text' name='p1q2'><br>");//第一页的问卷题目
55             out.println("<input type='submit' name='page' value='下一页'>");
56         }else if("下一页".equals(page)){
57             String p1q1=request.getParameter("p1q1");
58             String p1q2=request.getParameter("p1q2");
59             
60             //使用隐藏域
61 //            out.println("<input type='hidden' name='p1q1' value='"+p1q1+"'>");
62 //            out.println("<input type='hidden' name='p1q2' value='"+p1q2+"'>");
63             
64             //使用HttpSession存储第一页的答案
65             HttpSession session=request.getSession();
66             session.setAttribute("p1q1", p1q1);
67             session.setAttribute("p1q2", p1q2);
68             
69             out.println("问题三:<input type='text' name='p2q1'><br>");//第二页的问卷题目
70             //out.println("问题四:<input type='text' name='p2q2'><br>");            
71             out.println("<input type='submit' name='page' value='完成'>");//第一页问卷答案,使用隐藏域发送答案
72         }else if("完成".equals(page)){
73             
74             HttpSession session=request.getSession();
75             session.getAttribute("p1q1");
76             
77             out.println(session.getAttribute("p1q1")+"<br>");
78             out.println(session.getAttribute("p1q2")+"<br>");
79             out.println(request.getParameter("p2q1")+"<br>");//问卷结果网页
80         }
81         out.println("</form>");
82         out.println("</body>");
83         out.println("</html>");
84         out.close();
85     }
86 
87     /**
88      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
89      */
90     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
91         // TODO Auto-generated method stub
92         processRequest(request,response);
93     }
94 
95 }
Questionnaire.java

  使用隐藏域的方式,在关掉网页后,显然会丢失先前的请求的信息,所以仅适合用于一些简单的状态管理,如在线问卷。在查看网页源代码时,就可以看到隐藏域的值,这个方法不适合隐秘性较高的数据。

2、使用Cookie

  Cookie是在浏览器存储信息的一种方式,服务器可以响应浏览器set-cookie标头,浏览器收到这个标头与数值后,会将它以文件的形式存储在计算机上,这个文件就是Cookie。可以给Cookie设定一个存活期限,保留一些有用的信息在客户端,如果在关闭浏览器之后,再次打开浏览器并连接服务器时,这些cookie仍在有效期限中,浏览器会使用cookie标头自动将Cookie发送给服务器,服务器就可以得知一些先前请求的信息。

  如果创建Cookie,可以使用Cookie类,创建时指定Cookie中的名称与数值,并使用HttpServletResponse的addCookie()方法在响应中新增Cookie。例如:

    Cookie cookie=new Cookie("user","caterpillar");

    cookie.setMaxAge(7*24*60*60);//单位是秒,所以一星期有效

    response.addCookie(cookie);

  如果想要取得浏览器上存储的Cookie,则可以HttpServletRequest的getCookie()来取得,这可取得属于该网页所有域的所有Cookie,所以返回值时cookie[]数组。取得cookie对象后,可以使用Cookie的getName()与getValues()方法,分别取得Cookie的名称和数值。

    Cookie[] cookies=request.getCookies();

    if(cookies != null){

      for(Cookie cookie : cookies){

        String name = cookie.getName();

        String value = cookie.getValue();

      }

    }

  例2:用Cookie实现自动登录功能。当访问首页时,会检查用户先前时是否允许自动登录,如果是的话,就直接转送至用户界面。

 1 package Session.Management;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.Cookie;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 /**
13  * Servlet implementation class Index
14  */
15 @WebServlet("/index.do")
16 public class Index extends HttpServlet {
17     private static final long serialVersionUID = 1L;
18        
19     /**
20      * @see HttpServlet#HttpServlet()
21      */
22     public Index() {
23         super();
24         // TODO Auto-generated constructor stub
25     }
26 
27     /**
28      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
29      */
30     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
31         // TODO Auto-generated method stub
32         processRequest(request,response);
33     }
34 
35     private void processRequest(HttpServletRequest request,
36             HttpServletResponse response) throws IOException, ServletException {
37         // TODO Auto-generated method stub
38         Cookie[] cookies=request.getCookies();//取得Cookie
39         if(cookies!=null){
40             for(Cookie cookie:cookies){
41                 String name=cookie.getName();
42                 String value=cookie.getValue();
43                 if("user".equals(name)&&"caterpillar".equals(value)){
44                     request.setAttribute(name, value);
45                     request.getRequestDispatcher("/user.view").forward(request, response);
46                     return;
47                 }
48             }
49         }
50         response.sendRedirect("index.html");//如果没有相对应的Cookie名称与数值,表示尚未允许自动登录,重定向到登录窗体。
51         
52     }
53 
54     /**
55      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
56      */
57     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
58         // TODO Auto-generated method stub
59         processRequest(request,response);
60     }
61 
62 }
autoindex.java

  运行结果:

    

 1 package Session.Management;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.Cookie;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 /**
13  * Servlet implementation class Login1
14  */
15 @WebServlet("/login1.do")
16 public class Login1 extends HttpServlet {
17     private static final long serialVersionUID = 1L;
18        
19     /**
20      * @see HttpServlet#HttpServlet()
21      */
22     public Login1() {
23         super();
24         // TODO Auto-generated constructor stub
25     }
26 
27     /**
28      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
29      */
30     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
31         // TODO Auto-generated method stub
32     }
33 
34     /** 
35      * *-
36      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
37      */
38     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
39         // TODO Auto-generated method stub
40         String user=request.getParameter("user");
41         String passwd=request.getParameter("password");
42         if("nihao".equals(user)&&"123456789".equals(passwd)){
43 //            String login=request.getParameter("login");
44 //            if("auto".equals(login)){
45 //                Cookie cookie=new Cookie("user", "nihao");
46 //                cookie.setMaxAge(7*24*60*60);
47 //                response.addCookie(cookie);
48 //            }
49             //request.setAttribute("user", user);
50             
51             request.getSession().setAttribute("login", user);
52             
53             request.getRequestDispatcher("user.view").forward(request, response);
54         }else{
55             response.sendRedirect("index.html");
56         }
57     }
58 
59 }
autologin.java
 1 package Session.Management;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.annotation.WebServlet;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 import javax.servlet.http.HttpSession;
12 
13 /**
14  * Servlet implementation class User
15  */
16 @WebServlet("/user.view")
17 public class User extends HttpServlet {
18     private static final long serialVersionUID = 1L;
19        
20     /**
21      * @see HttpServlet#HttpServlet()
22      */
23     public User() {
24         super();
25         // TODO Auto-generated constructor stub
26     }
27 
28     /**
29      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
30      */
31     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
32         // TODO Auto-generated method stub
33         processRequest(request,response);
34     }
35 
36     private void processRequest(HttpServletRequest request,
37             HttpServletResponse response) throws IOException {
38         // TODO Auto-generated method stub
39         response.setContentType("text/html;charset=UTF-8");
40         HttpSession session=request.getSession();
41         if(session.getAttribute("login")==null){
42             response.sendRedirect("index.html");
43         }else{    
44             PrintWriter out=response.getWriter();
45             out.println("<!DOCTYPE html>");
46             out.println("<html>");
47             out.println("<head>");
48             out.println("<meta content='text/html; charset=UTF-8' http-equiv='content-type'>");
49             out.println("<title>欢迎"+session.getAttribute("login")+"</title>");
50             out.println("</head>");
51             out.println("<body>");
52             out.println("<h1>用户 "+session.getAttribute("login")+"已登录</h1><br><br>");
53             out.println("<a href='logout.view'>注销</a>");
54             out.println("</body>");
55             out.println("</html>");
56             out.close();
57         }
58         
59     }
60 
61     /**
62      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
63      */
64     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
65         // TODO Auto-generated method stub
66         processRequest(request,response);
67     }
68 
69 }
User.java

  当登录名正确时候,下次再次登录atuoindex.java时就会自动登录,并转到user.java

3、使用URL重写

  所谓URL重写,其实就是GET请求参数的应用,当服务器响应浏览器上一次请求时,将某些信息以超链接的方式响应给浏览器,超链接中包括请求参数信息。

    

  例3:模拟搜索分页结果,比如当点击第五页的时候,就会显示第五页的内容。

 1 package Session.Management;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.annotation.WebServlet;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 /**
13  * Servlet implementation class Search
14  */
15 @WebServlet("/search")
16 public class Search extends HttpServlet {
17     private static final long serialVersionUID = 1L;
18        
19     /**
20      * @see HttpServlet#HttpServlet()
21      */
22     public Search() {
23         super();
24         // TODO Auto-generated constructor stub
25     }
26 
27     /**
28      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
29      */
30     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
31         // TODO Auto-generated method stub
32         response.setContentType("text/html;charset=UTF-8");
33         
34         PrintWriter out=response.getWriter();
35         out.println("<!DOCTYPE html>");
36         out.println("<html>");
37         out.println("<head>");
38         out.println("<meta content='text/html; charset=UTF-8' http-equiv='content-type'>");
39         out.println("<title>搜索结果</title>");
40         out.println("</head>");
41         out.println("<body>");
42         String start=request.getParameter("start");
43         while(start==null){
44             start="1";
45         }
46         int count=Integer.parseInt(start);
47         int begin=10*count-9;
48         int end=10*count;
49         out.println("第 "+begin+" 到 "+end+" 搜索结果<br>");
50         out.println("<ul>");
51         for(int i=1;i<=10;i++){
52             out.println("<li>搜寻结果"+i+"</li>");
53         }
54         out.println("</ul>");
55         for(int i=1;i<10;i++){
56             if(i==count){
57                 out.println(i);
58                 continue;
59             }
60             out.println("<a href='search?start="+i+"'>"+i+"</a>");
61         }
62         out.println("</body>");
63         out.println("</html>");
64         out.close();
65     }
66 
67     /**
68      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
69      */
70     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
71         // TODO Auto-generated method stub
72         
73     }
74 
75 }
Search.java

  运行结果:

    

二、HttpSession会话管理

   可以将必须共享的数据,保存在HttpSession中成为属性,当关掉浏览器接收Cookie的功能,HttpSession也可以改用URL重写继续其会话管理。

1、使用HttpSession

  使用HttpServletRequest的getSession()方法取得HttpSession对象。

    HttpSession session =  request.getSession();

  HttpSession最常用的方法大概是setAttribute()与getAttribute(),这与HttpServletRequest的setAttribute()和getAttribute()类似,可以让你在对象中设置及取得属性,这是可以存放属性的第二个地方。(ServletAPI 中第三个可以存放属性的地方是在ServletContext中)。

  例3:将例1的在线问答,从隐藏域改为HttpSession方式来实现会话管理。

 1 package Session.Management;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 import java.io.UnsupportedEncodingException;
 6 
 7 import javax.servlet.ServletException;
 8 import javax.servlet.annotation.WebServlet;
 9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 import javax.servlet.http.HttpSession;
13 
14 /**
15  * Servlet implementation class Questionnaire
16  */
17 @WebServlet("/questionnaire")
18 public class Questionnaire extends HttpServlet {
19     private static final long serialVersionUID = 1L;
20        
21     /**
22      * @see HttpServlet#HttpServlet()
23      */
24     public Questionnaire() {
25         super();
26         // TODO Auto-generated constructor stub
27     }
28 
29     /**
30      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
31      */
32     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
33         // TODO Auto-generated method stub
34         processRequest(request,response);
35     }
36 
37     private void processRequest(HttpServletRequest request,
38             HttpServletResponse response) throws IOException {
39         // TODO Auto-generated method stub
40         request.setCharacterEncoding("UTF-8");
41         response.setContentType("text/html;charset=UTF-8");
42         PrintWriter out=response.getWriter();
43         out.println("<!DOCTYPE html>");
44         out.println("<html>");
45         out.println("<head>");
46         out.println("<meta content='text/html; charset=UTF-8' http-equiv='content-type'>");
47         out.println("<title>Questionnaire</title>");
48         out.println("</head>");
49         out.println("<body>");
50         String page=request.getParameter("page");//page请求参数决定哪一个页面问卷
51         out.println("<form action='questionnaire' method='post'>");
52         if(page==null){
53             out.println("问题一:<input type='text' name='p1q1'><br>");
54             out.println("问题二:<input type='text' name='p1q2'><br>");//第一页的问卷题目
55             out.println("<input type='submit' name='page' value='下一页'>");
56         }else if("下一页".equals(page)){
57             String p1q1=request.getParameter("p1q1");
58             String p1q2=request.getParameter("p1q2");
59             
60             //使用隐藏域
61 //            out.println("<input type='hidden' name='p1q1' value='"+p1q1+"'>");
62 //            out.println("<input type='hidden' name='p1q2' value='"+p1q2+"'>");
63             
64             //使用HttpSession存储第一页的答案
65             HttpSession session=request.getSession();
66             session.setAttribute("p1q1", p1q1);
67             session.setAttribute("p1q2", p1q2);
68             
69             out.println("问题三:<input type='text' name='p2q1'><br>");//第二页的问卷题目
70             //out.println("问题四:<input type='text' name='p2q2'><br>");            
71             out.println("<input type='submit' name='page' value='完成'>");//第一页问卷答案,使用隐藏域发送答案
72         }else if("完成".equals(page)){
73             
74             HttpSession session=request.getSession();
75             session.getAttribute("p1q1");
76             
77             out.println(session.getAttribute("p1q1")+"<br>");
78             out.println(session.getAttribute("p1q2")+"<br>");
79             out.println(request.getParameter("p2q1")+"<br>");//问卷结果网页
80         }
81         out.println("</form>");
82         out.println("</body>");
83         out.println("</html>");
84         out.close();
85     }
86 
87     /**
88      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
89      */
90     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
91         // TODO Auto-generated method stub
92         processRequest(request,response);
93     }
94 
95 }
Questionnaire.java

  默认在浏览器关闭之前,取得HttpSession都是相同的实例。如果在次会话期间,直接让目前的HttpSession失效,可以执行HttpSession的invalidate()方法,一个使用的时机是实现注销机制。

  例4:注销机制。

 1 package Session.Management;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.Cookie;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 /**
13  * Servlet implementation class Login1
14  */
15 @WebServlet("/login1.do")
16 public class Login1 extends HttpServlet {
17     private static final long serialVersionUID = 1L;
18        
19     /**
20      * @see HttpServlet#HttpServlet()
21      */
22     public Login1() {
23         super();
24         // TODO Auto-generated constructor stub
25     }
26 
27     /**
28      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
29      */
30     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
31         // TODO Auto-generated method stub
32     }
33 
34     /** 
35      * *-
36      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
37      */
38     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
39         // TODO Auto-generated method stub
40         String user=request.getParameter("user");
41         String passwd=request.getParameter("password");
42         if("nihao".equals(user)&&"123456789".equals(passwd)){
43 //            String login=request.getParameter("login");
44 //            if("auto".equals(login)){
45 //                Cookie cookie=new Cookie("user", "nihao");
46 //                cookie.setMaxAge(7*24*60*60);
47 //                response.addCookie(cookie);
48 //            }
49             //request.setAttribute("user", user);
50             
51             request.getSession().setAttribute("login", user);
52             
53             request.getRequestDispatcher("user.view").forward(request, response);
54         }else{
55             response.sendRedirect("index.html");
56         }
57     }
58 
59 }
Login.java 
 1 package Session.Management;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.annotation.WebServlet;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 import javax.servlet.http.HttpSession;
12 
13 /**
14  * Servlet implementation class Logout
15  */
16 @WebServlet("/logout.view")
17 public class Logout extends HttpServlet {
18     private static final long serialVersionUID = 1L;
19   
20 
21     /**
22      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
23      */
24     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
25         // TODO Auto-generated method stub
26         response.setContentType("text/html;charset=UTF-8");
27         HttpSession session=request.getSession();
28         String user=(String) session.getAttribute("login");
29         session.invalidate();//使HttpSession失效
30         
31         PrintWriter out=response.getWriter();
32         out.println("<!DOCTYPE html>");
33         out.println("<html>");
34         out.println("<head>");
35         out.println("<meta content='text/html; charset=UTF-8' http-equiv='content-type'>");
36         out.println("<title>注销</title>");
37         out.println("</head>");
38         out.println("<body>");
39         out.println("<h1>用户 "+user+"已注销</h1>");
40         out.println("</body>");
41         out.println("</html>");
42         out.close();
43     }
44 
45     
46 
47 }
Logout.java

2、HttpSession会话管理原理

  尝试运行HttpServletRequest的getSession()时,web容器会创建HttpSession()对象,关键在每个HttpSession对象都有个特殊的ID,成为Session ID,你可以执行HttpSession的getId()来取得Session ID。这个Session ID会默认使用Cookie存放在浏览器中。当浏览器请求应用程序时,会找Cookie存放的Session ID一并发送给应用程序,Web容器会根据Session ID来找出对应的HttpSession对象,这样就可以取得各浏览器个别的会话数据。

    

  使用HttpSession来进行进行会话管理时,设定为属性的对象是存储在服务器端,而Session ID默认使用Cookie存放于浏览器端。web容器存储Session ID的Cookie默认为关闭浏览器就失效。(默认关闭浏览器会马上失效的是浏览器上的Cookie,而不是HttpSession,要让HttpSesson立即失效必须运行invalidate()方法,或者等到设定的失效期间过后才会被容器销毁回收。)

  使用setMaxInactiveInterval()方法,设定浏览器多久没有请求的话,HttpSession自动失效。

3、HttpSession与URL重写

  HttpSession默认使用Cookie存储Session ID,如果用户关闭浏览器接收Cookie的功能,就无法使用Cookie在浏览器存储SessionID,如果在用户禁用Cookie的情况下,扔打算用HttpSession来进行会话管理,就可以搭配URL重写,向浏览器响应一段超链接,超链接URL后附加Session ID,当用户点击超链接时,将Session ID以GET请求发送给Web应用程序。

  如:<a href='"+response.encodeURL("counter")+"'>递增</a>

  例5:实现页面自增1

 1 package Session.Management;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.annotation.WebServlet;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 import javax.servlet.http.HttpSession;
12 
13 /**
14  * Servlet implementation class Counter
15  */
16 @WebServlet("/counter")
17 public class Counter extends HttpServlet {
18     private static final long serialVersionUID = 1L;
19  
20     /**
21      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
22      */
23     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
24         // TODO Auto-generated method stub
25         response.setContentType("text/html;charset=UTF-8");
26         
27         PrintWriter out=response.getWriter();
28         int count=0;
29         HttpSession session=request.getSession();
30         if(session.getAttribute("count")!=null){
31             Integer c=(Integer) session.getAttribute("count");
32             count=c+1;
33         }
34         session.setAttribute("count", count);
35         out.println("<!DOCTYPE html>");
36         out.println("<html>");
37         out.println("<head>");
38         out.println("<meta content='text/html; charset=UTF-8' http-equiv='content-type'>");
39         out.println("<title>注销</title>");
40         out.println("</head>");
41         out.println("<body>");
42         out.println("<h1>Servlet Count "+count+"</h1>");
43         out.println("<a href='"+response.encodeURL("counter")+"'>递增</a>");//使用encodeURL
44         out.println("</body>");
45         out.println("</html>");
46         out.close();
47     }
48 }
count.java

   运行结果:

     

 

当神已无能为力,那便是魔渡众生
目录
相关文章
|
6月前
|
存储 缓存 搜索推荐
session 详解:掌握客户端会话管理
session 详解:掌握客户端会话管理
|
6月前
|
存储 缓存 JSON
【Web开发】会话管理与无 Cookie 环境下的实现策略
【Web开发】会话管理与无 Cookie 环境下的实现策略
|
6月前
|
存储 缓存
实现单点登录的方式
实现单点登录的方式
86 1
|
6月前
|
安全 搜索推荐 Java
【SpringSecurity6.x】会话管理
【SpringSecurity6.x】会话管理
81 0
|
6月前
|
XML 缓存 Java
Shiro - 会话管理与SessionDao持久化Session
Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如web容器tomcat),不管JavaSE还是JavaEE环境都可以使用,提供了会话管理、会话事件监听、会话存储/持久化、容器无关的集群、失效/过期支持、对Web 的透明支持、SSO 单点登录的支持等特性。
270 0
|
JSON 监控 前端开发
OIDC协议会话管理相关技术介绍
## 介绍 > OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 [[RFC6749]](https://openid.net/specs/openid-connect-session-1_0.html#RFC6749) protocol. It enables Clients to verify the i
1123 0
OIDC协议会话管理相关技术介绍
|
存储 缓存 开发框架
shiro会话管理
Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如Tomcat、WebLogic),不管是J2SE还是J2EE环境都可以使用,提供了会话管理,会话事件监听,会话存储/持久化,容器无关的集群,失效/过期支持,对Web的透明支持,SSO单点登录的支持等特性。
|
数据库 Python 内存技术
用户认证系统
建立用户认证系统需要经过以下几步: app/__init__.py中声明并初始化数据库扩展 app/models.py中定义模型 app/auth/__init__.
1012 0
|
缓存 安全 数据安全/隐私保护
会话管理
会话管理
306 0
|
存储 PHP 数据安全/隐私保护
SSO单点登录三种情况的实现方式详解
单点登录(SSO——Single Sign On)对于我们来说已经不陌生了。对于大型系统来说使用单点登录可以减少用户很多的麻烦。就拿百度来说吧,百度下面有很多的子系统——百度经验、百度知道、百度文库等等,如果我们使用这些系统的时候,每一个系统都需要我们输入用户名和密码登录一次的话,我相信用户体验肯定会直线下降。
1586 0