Servlets - 会话跟踪( Session Tracking)
HTTP是一种“无状态”协议,这意味着每次客户端检索网页时,客户端都会打开与Web服务器的单独连接,服务器自动不会保留以前客户端请求的任何记录。
仍然有以下三种方法来维护Web客户端和Web服务器之间的会话 -
Cookies
Web服务器可以将唯一的会话ID作为cookie分配给每个Web客户端,并且对于来自客户端的后续请求,可以使用收到的cookie来识别它们。
这可能不是一种有效的方法,因为很多时候浏览器不支持cookie,因此我不建议使用此过程来维护会话。
隐藏的表单字段
Web服务器可以发送隐藏的HTML表单字段以及唯一的会话ID,如下所示 -
<input type = "hidden" name = "sessionid" value = "12345">
此条目表示在提交表单时,指定的名称和值将自动包含在GET或POST数据中。 每次Web浏览器发回请求时,session_id值都可用于保持不同Web浏览器的跟踪。
这可能是跟踪会话的有效方式,但单击常规()超文本链接不会导致表单提交,因此隐藏的表单字段也不能支持常规会话跟踪。
URL重写
您可以在标识会话的每个URL的末尾附加一些额外数据,并且服务器可以将该会话标识符与其存储的有关该会话的数据相关联。
例如,使用http://iowiki.com/file.htm;sessionid = 12345,会话标识符作为sessionid = 12345附加,可以在Web服务器上访问该标识符以标识客户端。
URL重写是维护会话的更好方法,即使浏览器不支持cookie也能正常工作。 URL重写的缺点是,您必须动态生成每个URL以分配会话ID,即使是简单的静态HTML页面也是如此。
HttpSession对象
除了上面提到的三种方式之外,servlet还提供了HttpSession接口,它提供了一种在多个页面请求中识别用户或访问网站并存储有关该用户的信息的方法。
servlet容器使用此接口在HTTP客户端和HTTP服务器之间创建会话。 会话在指定的时间段内持续存在,来自用户的多个连接或页面请求。
您将通过调用HttpServletRequest的公共方法getSession()来获取HttpSession对象,如下所示 -
HttpSession session = request.getSession();
在将任何文档内容发送到客户端之前,需要调用request.getSession() 。 以下是HttpSession对象可用的重要方法的摘要 -
Sr.No. | 方法和描述 |
---|---|
1 | public Object getAttribute(String name) 此方法返回在此会话中使用指定名称绑定的对象,如果名称下没有绑定任何对象,则返回null。 |
2 | public Enumeration getAttributeNames() 此方法返回Enumeration of String对象,其中包含绑定到此会话的所有对象的名称。 |
3 | public long getCreationTime() 此方法返回创建此会话的时间,以格林威治标准时间1970年1月1日午夜以来的毫秒数为单位进行测量。 |
4 | public String getId() 此方法返回包含分配给此会话的唯一标识符的字符串。 |
5 | public long getLastAccessedTime() 此方法以格林威治标准时间1970年1月1日午夜以来的毫秒格式返回会话的最后访问时间 |
6 | public int getMaxInactiveInterval() 此方法返回最大时间间隔(秒),servlet容器将在客户端访问之间保持会话打开。 |
7 | public void invalidate() 此方法使此会话无效并取消绑定绑定到它的任何对象。 |
8 | public boolean isNew( 如果客户端尚未了解会话或客户端选择不加入会话,则此方法返回true。 |
9 | public void removeAttribute(String name) 此方法从此会话中删除与指定名称绑定的对象。 |
10 | public void setAttribute(String name, Object value) 此方法使用指定的名称将对象绑定到此会话。 |
11 | public void setMaxInactiveInterval(int interval) 此方法指定servlet容器使此会话失效之前的客户端请求之间的时间(以秒为单位)。 |
会话跟踪示例
此示例描述如何使用HttpSession对象查找会话的创建时间和上次访问时间。 如果一个新会话尚不存在,我们会将该会话与该请求相关联。
// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
// Extend HttpServlet class
public class SessionTrack extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Create a session object if it is already not created.
HttpSession session = request.getSession(true);
// Get session creation time.
Date createTime = new Date(session.getCreationTime());
// Get last access time of this web page.
Date lastAccessTime = new Date(session.getLastAccessedTime());
String title = "Welcome Back to my website";
Integer visitCount = new Integer(0);
String visitCountKey = new String("visitCount");
String userIDKey = new String("userID");
String userID = new String("ABCD");
// Check if this is new comer on your web page.
if (session.isNew()) {
title = "Welcome to my website";
session.setAttribute(userIDKey, userID);
} else {
visitCount = (Integer)session.getAttribute(visitCountKey);
visitCount = visitCount + 1;
userID = (String)session.getAttribute(userIDKey);
}
session.setAttribute(visitCountKey, visitCount);
// Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String docType =
"<!doctype html public \"-//w3c//dtd html 4.0 " +
"transitional//en\">\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor = \"#f0f0f0\">\n" +
"<h1 align = \"center\">" + title + "</h1>\n" +
"<h2 align = \"center\">Session Infomation</h2>\n" +
"<table border = \"1\" align = \"center\">\n" +
"<tr bgcolor = \"#949494\">\n" +
" <th>Session info</th><th>value</th>
</tr>\n" +
"<tr>\n" +
" <td>id</td>\n" +
" <td>" + session.getId() + "</td>
</tr>\n" +
"<tr>\n" +
" <td>Creation Time</td>\n" +
" <td>" + createTime + " </td>
</tr>\n" +
"<tr>\n" +
" <td>Time of Last Access</td>\n" +
" <td>" + lastAccessTime + " </td>
</tr>\n" +
"<tr>\n" +
" <td>User ID</td>\n" +
" <td>" + userID + " </td>
</tr>\n" +
"<tr>\n" +
" <td>Number of visits</td>\n" +
" <td>" + visitCount + "</td>
</tr>\n" +
"</table>\n" +
"</body>
</html>"
);
}
}
编译上面的servlet SessionTrack并在web.xml文件中创建适当的条目。 现在运行http://localhost:8080/SessionTrack会在第一次运行时显示以下结果 -
<h1 align="center">Welcome to my website</h1>
<h2 align="center">Session Infomation</h2>
会话信息 | 值 |
---|---|
id | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
创作时间 | Tue Jun 08 17:26:40 GMT + 04:00 2010 |
最后访问时间 | Tue Jun 08 17:26:40 GMT + 04:00 2010 |
用户身份 | ABCD |
访问次数 | 0 |
现在尝试第二次运行相同的servlet,它将显示以下结果。
<h1 align="center">Welcome Back to my website</h1>
<h2 align="center">Session Infomation</h2>
信息类型 | 值 |
---|---|
id | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
创作时间 | Tue Jun 08 17:26:40 GMT + 04:00 2010 |
最后访问时间 | Tue Jun 08 17:26:40 GMT + 04:00 2010 |
用户身份 | ABCD |
访问次数 | 1 |
删除会话数据
完成用户的会话数据后,您有多种选择 -
Remove a particular attribute - 您可以调用public void removeAttribute(String name)方法来删除与特定键关联的值。
Delete the whole session - 您可以调用public void invalidate()方法来丢弃整个会话。
Setting Session timeout - 您可以调用public void setMaxInactiveInterval(int interval)方法来单独设置会话的超时。
Log the user out - 支持servlet 2.4的服务器,您可以调用logout将客户端记录到Web服务器之外,并使属于所有用户的所有会话无效。
web.xml Configuration - 如果您使用的是Tomcat,除了上述方法之外,您还可以在web.xml文件中配置会话超时,如下所示。
<session-config>
<session-timeout>15</session-timeout>
</session-config>
超时以分钟表示,并覆盖Tomcat中的默认超时30分钟。
servlet中的getMaxInactiveInterval()方法以秒为单位返回该会话的超时时间。 因此,如果您的会话在web.xml中配置了15分钟,则getMaxInactiveInterval()将返回900。