会话管理

一、会话管理的基本原理

  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

   运行结果:

     

时间: 2024-10-14 21:54:01

会话管理的相关文章

(转)web会话管理方式

阅读目录 1. 基于server端session的管理 2. cookie-based的管理方式 3. token-based的管理方式 4. 安全问题 5. 总结 http是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的.当然它知道是哪个客户端地址发过来的,但是对于我们的应用来说,我们是靠用户来管理,而不是靠客户端.所以对我们的应用而言,它是需要有状态管理的,以便服务端能够准确的知道http请求是哪个用户发起的,从而判断他是否有权限继续这个请求.这

会话管理(Cookie/Session技术)

什么是会话:用户打开浏览器,点击多个超链接,访问服务器的多个web资源,然后关闭浏览器,整个过程就称为一个会话: 会话过程需要解决的问题:每个用户在使用浏览器与服务器进行会话的过程中,都可能会产生一些数据,这些输入如何来进行保存?比如用户在购物网站浏览的商品记录,用户添加购物车的记录等等这些信息如何进行存储?在程序中会话跟踪是一件非常重要的事情,一个用户的所有请求操作都应该属于同一个会话,而另一个人的所有请求操作应该属于另一个人,二者不能混淆!当想到需要在保存数据时,我们首先肯定会想到使用域对象

集群增量会话管理器——DeltaManager

DeltaManager会话管理器是tomcat默认的集群会话管理器,它主要用于集群中各个节点之间会话状态的同步维护,由于相关内容涉及到集群,可能会需要一些集群通信相关知识,如果有疑问可结合集群相关章节. 集群增量会话管理器的职责是将某节点的会话该变同步到集群内其他成员节点上,它属于全节点复制模式,所谓全节点复制是指集群中某个节点的状态变化后需要同步到集群中剩余的节点,非全节点方式可能只是同步到其中某个或若干节点.在集群中全节点会话复制的一个大致步骤如下图所示,客户端发起一个请求,假设通过一定的

session management会话管理的原理

web请求与响应基于http,而http是无状态协议.所以我们为了跨越多个请求保留用户的状态,需要利用某种工具帮助我们记录与识别每一次请求及请求的其他信息.举个栗子,我们在淘宝购物的时候,首先添加了一本<C++ primer>进入购物车,然后我们又继续去搜索<thinking in java>,继续添加购物车,这时购物车应该有两本书.但如果我们不采取session management会话管理的话,基于http无状态协议,我们在第二次向购物车发出添加请求时,他是无法知道我们第一次添

Java中的会话管理——HttpServlet,Cookies,URL Rewriting(译)

参考谷歌翻译,关键字直接使用英文,原文地址:http://www.journaldev.com/1907/java-session-management-servlet-httpsession-url-rewriting Java Web应用程序中的会话管理(Session Management)是一个非常有趣的话题.Java Servlet中的会话通过不同的方式进行管理,例如Cookie,HttpSession API,URL重写等. 这是Java Web应用程序系列教程中的第三篇文章,您可能

JavaWeb基础—会话管理之Cookie

一.什么是会话 打开浏览器,浏览各种资源,点击各种超链接,直至关闭浏览器,整个过程称为会话 二.会话管理的两种技术 1.Cookie 基于客户端.以cookie的形式写给用户各自的浏览器.当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去. 2.Session 基于服务端.session类似于客户端在服务器端的账户.使用Map存放.服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象. 三.Cookie的用途 Cookie的用途: 服务器用来跟踪客户端状态

《白帽子讲WEB安全》学习笔记之第9章 认证与会话管理

第9章 认证与会话管理 9.1 who am i? 认证包含了身份和身份认证两层含义. q  身份-我是谁? q  身份认证-这就是我. 认证的目的就是为了认出用户是谁?而授权的目的是为了决定用户能够做什么. 认证实际上就是一个验证凭证的过程. 9.2 密码的那些事儿 一般为了安全与用户体验性,采用"双因素"验证的比较多,例如支付中的密码和手机动态密钥. 我认为在用户注册的时候应该检测一下用户使用的是否是弱密码.这就代表着我们需要在系统中建立一套"弱密码表",弱密码

笔记 - 会话管理(cookie、session)

关于路径 /** * web应用中路径问题 * @author APPle * */ public class PathDemo extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8

第十章 会话管理——《跟我学Shiro》

Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如web容器tomcat),不管JavaSE还是JavaEE环境都可以使用,提供了会话管理.会话事件监听.会话存储/持久化.容器无关的集群.失效/过期支持.对Web的透明支持.SSO单点登录的支持等特性.即直接使用Shiro的会话管理可以直接替换如Web容器的会话管理. 会话 所谓会话,即用户访问应用时保持的连接关系,在多次交互中应用能够识别出当前访问的用户是谁,且可以在多次交互中保存一些数据.如访问一些网站时登录成功后,网站可以记住用

OWASP WEB会话管理备忘单 阅读笔记

https://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Session_ID_Properties 会话简介 HTTP是一种无状态的协议,每一对请求和响应与其他的web交互是相互独立的,如果要跟踪用户的访问状态,就需要引入会话机制,对用户的访问序列进行管理. 会话管理,将认证和访问控制(也叫授权)连接起来,在认证之前可能有未认证的会话,在访问控制之后,要有会话销毁机制. 一旦认证的会话建立,会话ID就相当于最强的认证手段, 等