根据设计,HTTP是一种无状态的协议。它意味着Web应用并不了解有关同一用户以前请求的信息。维持会话状态信息的方法之一是使用Servlet或者JSP容器提供的会话跟踪功能。Servlet API规范定义了一个简单的HttpSession接口,通过它我们可以方便地实现会话跟踪。
HttpSession接口提供了存储和返回标准会话属性的方法。标准会话属性如会话标识符、应用数据等,都以“名字-值”对的形式保存。简而言之,HttpSession接口提供了一种把对象保存到内存、在同一用户的后继请求中提取这些对象的标准办法。在会话中保存数据的方法是setAttribute(String s, Object o),从会话提取原来所保存对象的方法是getAttribute(String s)。
在HTTP协议中,当用户不再活动时不存在显式的终止信号。由于这个原因,我们不知道用户是否还要再次返回,如果不采取某种方法解决这个问题,内存中会积累起大量的HttpSession对象。
为此,Servlet采用“超时限制”的办法来判断用户是否还在访问:如果某个用户在一定的时间之内没有发出后继请求,则该用户的会话被作废,他的HttpSession对象被释放。会话的默认超时间隔由Servlet容器定义。这个值可以通过getMaxInactiveInterval方法获得,通过setMaxInactiveInterval方法修改,这些方法中的超时时间以秒计。如果会话的超时时间值设置成-1,则会话永不超时。Servlet可以通过getLastAccessedTime方法获得当前请求之前的最后一次访问时间。
要获得HttpSession对象,我们可以调用HttpServletRequest对象的getSession方法。为了正确地维持会话状态,我们必须在发送任何应答内容之前调用getSession方法。
下面为一实例:
1 import javax.servlet.*; 2 import javax.servlet.http.*; 3 4 /** 5 * <p>This is a simple servlet that uses session tracking and 6 * Cookies to count the number of times a client session has 7 * accessed this servlet. 8 */ 9 10 public class Counter extends HttpServlet 11 { 12 // Define our counter key into the session 13 static final String COUNTER_KEY = "Counter.count"; 14 15 /** 16 * <p>Performs the HTTP GET operation 17 * 18 * @param req The request from the client 19 * @param resp The response from the servlet 20 */ 21 22 public void doGet(HttpServletRequest req,HttpServletResponse resp) 23 throws ServletException, java.io.IOException 24 { 25 // Get the session object for this client session. 26 // The parameter indicates to create a session 27 // object if one does not exist 28 HttpSession session = req.getSession(true); 29 30 // Set the content type of the response 31 resp.setContentType("text/html"); 32 33 // Get the PrintWriter to write the response 34 java.io.PrintWriter out = resp.getWriter(); 35 36 // Is there a count yet? 37 int count = 1; 38 Integer i = (Integer) session.getAttribute(COUNTER_KEY); 39 40 // If a previous count exists, set it 41 if (i != null) { 42 count = i.intValue() + 1; 43 } 44 45 // Put the count back into the session 46 session.setAttribute(COUNTER_KEY, new Integer(count)); 47 48 // Print a standard header 49 out.println("<html>"); 50 out.println("<head>"); 51 out.println("<title>Session Counter</title>"); 52 out.println("</head>"); 53 out.println("<body>"); 54 out.println("Your session ID is <b>" + 55 session.getId()); 56 out.println("</b> and you have hit this page <b>" + 57 count + 58 "</b> time(s) during this browser session"); 59 60 out.println("<form method=GET action=\"" + 61 req.getRequestURI() + "\">"); 62 out.println("<input type=submit " + 63 "value=\"Hit page again\">"); 64 out.println("</form>"); 65 66 // Wrap up 67 out.println("</body>"); 68 out.println("</html>"); 69 out.flush(); 70 } 71 72 public void init(ServletConfig cfg) throws ServletException 73 { 74 super.init(cfg); 75 } 76 77 public void destroy() 78 { 79 super.destroy(); 80 } 81 82 }
将此文件编译生成class文件,并拷贝入webapps\examples\WEB-INF\classes下
运行http://localhost:9090/examples/servlets/servlet/Counter即可看到结果,单击按钮可以看到次数改变