Servlet(4):Session

Session, Cookie及交互

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。

Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

 

HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录。

但是仍然有以下三种方式来维持 Web 客户端和 Web 服务器之间的 session 会话:

Cookies:Session创建成功以后,会创建Cookie(key='JSESSIONID', value=Session ID)。通常情况下,一个浏览器的多个Tag可以共享一个Session对象

隐藏的表单字段(Form适用):有些浏览器不支持Cookie,可以用表单隐藏域代替。

<input type="hidden" name="sessionid" value="12345">

URL 重写(Link适用):如果使用URL提交时,可以作为URL参数传递。

http://localhost:8080/ServletTest/login?sessionid=12345

 

下面是一个使用Cookie来维持Session会话的例子。重点代码讲解在例子中。

 1 package com.servlettest.session;
 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 Login
15  */
16 @WebServlet("/default")
17 public class Default extends HttpServlet {
18 
19     private static final long serialVersionUID = 1L;
20 
21     /**
22      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
23      */
24     @Override
25     protected void doGet(HttpServletRequest request, HttpServletResponse response)
26             throws ServletException, IOException {
27 
28         invalidateSession(request);
29 
30         response.setContentType("text/html");
31         request.setCharacterEncoding("UTF-8");
32         response.setCharacterEncoding("UTF-8");
33 
34         PrintWriter out = response.getWriter();
35         out.println("<!DOCTYPE html>");
36         out.println("<html>");
37         out.println("<head>");
38         out.println("<title>Login Page</title>");
39         out.println("</head>");
40         out.println("<body>");
41         out.println("<form action=\"login\" method=\"POST\">");
42         out.println("帐号: <input type=\"text\" name=\"userId\"/><br/>");
43         out.println("密码: <input type=\"password\" name=\"password\"/><br/>");
44         out.println("<input type=\"submit\" value=\"提交\"/>");
45 
46         // HttpServletRequest Attribute和Parameter的区别
47         // (1) HttpServletRequest 类有setAttribute()方法,而没有setParameter()方法。
48         // (2) 当两个Web组件之间为链接关系时,被链接的组件通过getParameter()方法来获得请求参数,一般通过表单和链接传递的参数使用getParameter。
49         // (3) 当两个Web组件之间为转发关系时,转发目标组件通过getAttribute()方法来和转发源组件共享request范围内的数据。
50         String message = (String) request.getAttribute("message");
51         if (message != null && message != "") {
52             out.println("<p>" + message + "</p>");
53         }
54         out.println("</body>");
55         out.println("</html>");
56     }
57 
58     /**
59      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
60      */
61     @Override
62     protected void doPost(HttpServletRequest request, HttpServletResponse response)
63             throws ServletException, IOException {
64         doGet(request, response);
65     }
66 
67     private static void invalidateSession(HttpServletRequest request) {
68         HttpSession session = request.getSession(false);
69         if (session != null)
70             session.invalidate();
71     }
72 }
 1 package com.servlettest.session;
 2 
 3 import java.io.IOException;
 4 import java.util.HashMap;
 5 import java.util.Map;
 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 Login
16  */
17 @WebServlet("/login")
18 public class Login extends HttpServlet {
19 
20     private static final long serialVersionUID = 1L;
21 
22     private static final Map<String, String[]> USER_INFO = initUserInfo();
23 
24     /**
25      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
26      */
27     @Override
28     protected void doGet(HttpServletRequest request, HttpServletResponse response)
29             throws ServletException, IOException {
30 
31         response.setContentType("text/html");
32 
33         request.setCharacterEncoding("UTF-8");
34         response.setCharacterEncoding("UTF-8");
35 
36         // 获取用户登录信息
37         String userId = request.getParameter("userId");
38         String password = request.getParameter("password");
39         if ((userId == null || userId == "") || (password == null || password == "")) {
40             request.getRequestDispatcher("/default").forward(request, response);
41         } else if (USER_INFO.containsKey(userId)) {
42             String[] info = USER_INFO.get(userId);
43             if (info[1].equals(password)) {
44                 // 创建Session
45                 setSession(userId, info[0], request, response);
46                 request.getRequestDispatcher("/welcome1").forward(request, response);
47             } else {
48                 request.setAttribute("message", "帐号或密码错误!");
49                 request.getRequestDispatcher("/default").forward(request, response);
50             }
51         } else {
52             request.setAttribute("message", "帐号或密码错误!");
53             request.getRequestDispatcher("/default").forward(request, response);
54         }
55     }
56 
57     /**
58      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
59      */
60     @Override
61     protected void doPost(HttpServletRequest request, HttpServletResponse response)
62             throws ServletException, IOException {
63         doGet(request, response);
64     }
65 
66     private static Map<String, String[]> initUserInfo() {
67 
68         Map<String, String[]> result = new HashMap<>();
69         String[] user1 = { "张三", "123" };
70         result.put("101", user1);
71         String[] user2 = { "李四", "456" };
72         result.put("102", user2);
73         String[] user3 = { "王五", "789" };
74         result.put("103", user3);
75 
76         return result;
77     }
78 
79     private void setSession(String userId, String userName, HttpServletRequest request, HttpServletResponse response) {
80         // 如果不存在 session 会话,则创建一个 session 对象
81         HttpSession session = request.getSession(true);
82         String[] userInfo = { userId, userName };
83         session.setAttribute("USER_INFO", userInfo);
84     }
85 }
 1 package com.servlettest.session;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 import java.util.Enumeration;
 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 Welcome
16  */
17 @WebServlet("/welcome1")
18 public class Welcome1 extends HttpServlet {
19 
20     private static final long serialVersionUID = 1L;
21 
22     /**
23      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
24      */
25     @Override
26     protected void doGet(HttpServletRequest request, HttpServletResponse response)
27             throws ServletException, IOException {
28 
29         response.setContentType("text/html");
30         request.setCharacterEncoding("UTF-8");
31         response.setCharacterEncoding("UTF-8");
32 
33         // 注意request.getSession() 等同于 request.getSession(true),除非我们确认session一定存在或者sesson不存在时明确有创建session的需要,否则请尽量使用request.getSession(false)
34         HttpSession session = request.getSession(false);
35         String[] userInfo = (String[]) session.getAttribute("USER_INFO");
36         PrintWriter out = response.getWriter();
37         out.println("<!DOCTYPE html>");
38         out.println("<html>");
39         out.println("<head>");
40         out.println("<title>Login Page</title>");
41         out.println("</head>");
42         out.println("<body>");
43         out.println("您好 <b>" + userInfo[0] + "-" + userInfo[1] + "</b>, 这是Welcome1画面!");
44         out.println("<br/><a href = \"welcome2\">去welcome2</a> | <a href = \"default\">注销</a>");
45         out.println("<br/>");
46         out.println("<p>SessionID: " + session.getId() + "</p>");
47         Enumeration<String> names = session.getAttributeNames();
48         while (names.hasMoreElements()) {
49             String name = names.nextElement();
50             out.println("<p>" + names.nextElement() + ": " + session.getAttribute(name) + "</p>");
51         }
52         out.println("</table>");
53         out.println("</body>");
54         out.println("</html>");
55         out.close();
56     }
57 
58     /**
59      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
60      */
61     @Override
62     protected void doPost(HttpServletRequest request, HttpServletResponse response)
63             throws ServletException, IOException {
64         doGet(request, response);
65     }
66 }
 1 package com.servlettest.session;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 import java.util.Enumeration;
 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 Welcome
16  */
17 @WebServlet("/welcome2")
18 public class Welcome2 extends HttpServlet {
19 
20     private static final long serialVersionUID = 1L;
21 
22     /**
23      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
24      */
25     @Override
26     protected void doGet(HttpServletRequest request, HttpServletResponse response)
27             throws ServletException, IOException {
28 
29         response.setContentType("text/html");
30         request.setCharacterEncoding("UTF-8");
31         response.setCharacterEncoding("UTF-8");
32 
33         // 注意request.getSession() 等同于 request.getSession(true),除非我们确认session一定存在或者sesson不存在时明确有创建session的需要,否则请尽量使用request.getSession(false)
34         HttpSession session = request.getSession(false);
35         String[] userInfo = (String[]) session.getAttribute("USER_INFO");
36         PrintWriter out = response.getWriter();
37         out.println("<!DOCTYPE html>");
38         out.println("<html>");
39         out.println("<head>");
40         out.println("<title>Login Page</title>");
41         out.println("</head>");
42         out.println("<body>");
43         out.println("您好 <b>" + userInfo[0] + "-" + userInfo[1] + "</b>, 这是Welcome2画面!");
44         out.println("<br/><a href = \"welcome1\">去welcome1</a> | <a href = \"default\">注销</a>");
45         out.println("<br/>");
46         out.println("<p>SessionID: " + session.getId() + "</p>");
47         Enumeration<String> names = session.getAttributeNames();
48         while (names.hasMoreElements()) {
49             String name = names.nextElement();
50             out.println("<p>" + names.nextElement() + ": " + session.getAttribute(name) + "</p>");
51         }
52         out.println("</body>");
53         out.println("</html>");
54         out.close();
55     }
56 
57     /**
58      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
59      */
60     @Override
61     protected void doPost(HttpServletRequest request, HttpServletResponse response)
62             throws ServletException, IOException {
63         doGet(request, response);
64     }
65 }
 1 package com.servlettest.filter;
 2 
 3 import java.io.IOException;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 import javax.servlet.Filter;
 8 import javax.servlet.FilterChain;
 9 import javax.servlet.FilterConfig;
10 import javax.servlet.ServletException;
11 import javax.servlet.ServletRequest;
12 import javax.servlet.ServletResponse;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15 import javax.servlet.http.HttpSession;
16 
17 import com.servlettest.exception.PermissionException;
18 
19 public class PermissionFilter implements Filter {
20 
21     private final static List<String> URL = new ArrayList<>();
22 
23     @Override
24     public void init(FilterConfig arg0) throws ServletException {
25         URL.add("/ServletTest/welcome1");
26         URL.add("/ServletTest/welcome2");
27     }
28 
29     @Override
30     public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
31             throws IOException, ServletException {
32         if (arg0 instanceof HttpServletRequest && arg1 instanceof HttpServletResponse) {
33             HttpServletRequest req = (HttpServletRequest) arg0;
34             if (URL.contains(req.getRequestURI())) {
35                 HttpSession session = req.getSession(true);
36                 String[] userInfo = (String[]) session.getAttribute("USER_INFO");
37                 if (userInfo == null) {
38                     throw new PermissionException();
39                 }
40             }
41         }
42         arg2.doFilter(arg0, arg1);
43     }
44 
45     @Override
46     public void destroy() {
47     }
48 }
1 package com.servlettest.exception;
2 
3 public class PermissionException extends RuntimeException {
4 
5     private static final long serialVersionUID = 1L;
6 
7 }
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8"/>
 5 <title>Forbidden</title>
 6 </head>
 7 <body>
 8     <h2>403 禁止访问所请求的页面</h2>
 9 </body>
10 </html>
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 4     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
 5     id="WebApp_ID" version="3.1">
 6     <filter>
 7         <filter-name>permissionFilter</filter-name>
 8         <filter-class>com.servlettest.filter.PermissionFilter</filter-class>
 9     </filter>
10     <filter-mapping>
11         <filter-name>permissionFilter</filter-name>
12         <url-pattern>/*</url-pattern>
13     </filter-mapping>
14     <error-page>
15         <error-code>403</error-code>
16         <location>/html/forbidden.html</location>
17     </error-page>
18     <error-page>
19         <exception-type>com.servlettest.exception.PermissionException</exception-type>
20         <location>/html/forbidden.html</location>
21     </error-page>
22     <welcome-file-list>
23         <welcome-file>default</welcome-file>
24     </welcome-file-list>
25     <session-config>
26         <session-timeout>1</session-timeout>
27     </session-config>
28 </web-app>

 

posted @ 2017-09-11 21:50  Storm_L  阅读(189)  评论(0编辑  收藏  举报