会话管理

Posted Asu_PC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了会话管理相关的知识,希望对你有一定的参考价值。

一、会话管理的基本原理

  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方式来实现会话管理。