HTTP是一种“无状态”协议,这意味着每个客户端检索的网页时,客户端打开一个单独的连接到Web服务器,服务器会自动以前的客户端请求不保留任何记录。
不过也有以下三种方式来维护Web客户端和Web服务器之间的会话:
一个Web服务器可以分配一个唯一的会话ID作为一个cookie到每个Web客户端和客户端的后续请求可以确认接收的cookie。
这可能不是一个有效的方法,因为很多浏览器不支持cookie,所以我会建议不要使用这个程序来维护会话。
一个Web服务器可以发送一个隐藏的HTML表单字段,以及一个唯一的会话ID如下:
<input type="hidden" name="sessionid" value="12345">
该条目指的是,当表单被提交时,指定的名称和值会被自动包含在GET或POST数据。每次当web浏览器发送请求发送回,然后session_id值可以用于保持不同的Web浏览器的轨迹。
这可能是一个有效的方法,跟踪会话,但经常(<A HREF...>)超文本链接上单击不会导致一个表单提交,因此隐藏的表单字段也可以不支持常规的会话跟踪。
标识会话的每个URL的末尾,可以添加一些额外的数据和服务器相关联的会话标识符与数据存储有关该会话。
例如,http://tutorialspoint.com/file.htm;sessionid=12345,会话标识符sessionid= 12345可以访问Web服务器,以确定客户端连接。
URL重写是一种更好的方式来维持会话可以工作在当他们不支持Cookie,但是缺点是,会产生每动态地分配一个会话ID到URL,即使是在很简单的静态HTML页面。
除了上述的三种方法,servlet提供了HttpSession接口提供了一个方法来识别一个用户跨多个页面请求或访问一个网站,并存储有关该用户的信息。
使用这个接口,servlet容器创建一个HTTP客户端和HTTP服务器之间的会话。会话持续一个指定的时间段,跨多个连接或页面请求用户。
你会得到通过调用HttpSession对象的公共方法HttpServletRequest的getSession(),如下所示:
HttpSession session = request.getSession();
你需要调用request.getSession(),然后再发送任何文件的内容给客户端。下面是总结的HttpSession对象重要方法:
S.N. | 方法 & 描述 |
---|---|
1 |
public Object getAttribute(String name) 此方法返回在此会话具有指定名称的对象,如果没有对象被绑定名称下,则返回null约束。 |
2 |
public Enumeration getAttributeNames() 此方法返回一个String对象,其中包含的所有对象绑定到此会话的名称枚举。 |
3 |
public long getCreationTime() 此方法返回时此会话的创建,以1970年1月1日GMT午夜以来的毫秒数。 |
4 |
public String getId() 此方法返回一个字符串,其中包含的唯一标识符分配给此会话。 |
5 |
public long getLastAccessedTime() 此方法返回客户端发送一个请求与此会话有关的,最后一次为1970年1月1日GMT午夜以来的毫秒数。 |
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 - by www.gitbook.net 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会话跟踪,并在web.xml文件中创建相应的条目。现在运行http://localhost:8080/SessionTrack将显示如下的结果时,你会第一次运行:
Session info | value |
---|---|
id | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
Creation Time | Tue Jun 08 17:26:40 GMT+04:00 2010 |
Time of Last Access | Tue Jun 08 17:26:40 GMT+04:00 2010 |
User ID | ABCD |
Number of visits | 0 |
现在尝试运行相同的servlet第二遍,它会显示下面的结果。
info type | value |
---|---|
id | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
Creation Time | Tue Jun 08 17:26:40 GMT+04:00 2010 |
Time of Last Access | Tue Jun 08 17:26:40 GMT+04:00 2010 |
User ID | ABCD |
Number of visits | 1 |
当你完成了一个用户的会话数据,你有几种选择:
删除一个特定的属性: 你可以调用pubic void removeAttribute(String name)方法删除与特定的键关联的值。
删除整个会话: 你可以调用public void invalidate() 方法抛弃整个会话。
设置会话过期时间: 你可以调用 public void setMaxInactiveInterval(int interval) 方法来设置单独的会话超时。
注销用户: 支持servlet2.4服务器,你可以调用注销登录客户端的Web服务器,属于所有用户的所有会话无效。
web.xml 配置: 如果您使用的是Tomcat,除了上述方法,你可以配置会话超时在web.xml文件中如下。
<session-config> <session-timeout>15</session-timeout> </session-config>
在Tomcat中表示超时为分钟,超时将被覆盖默认的超时时间为30分钟。
在一个servlet 的 getMaxInactiveInterval()方法返回的超时时间,会话在几秒钟内。所以,如果在web.xml中配置会话为15分钟,那么getMaxInactiveInterval()返回应该是900。