HTTP是一种“无状态”协议,这意味着每次客户端检索网页时,客户端都会打开与Web服务器的单独连接,并且服务器不会自动保留先前客户端请求的任何记录。
所以,我们需要使用以下三种方式来维护Web客户端和Web服务器之间的会话:
Cookie
Web服务器可以将唯一的会话ID作为cookie分配给每个Web客户端,对于来自客户端的后续请求,可以使用接收到的cookie来识别它们。
这可能不是一种有效的方法,因为很多时候浏览器都不支持cookie,因此我不建议使用Cookie来维护会话。
隐藏表格栏位
Web服务器可以发送隐藏的HTML表单字段以及唯一的会话ID,如下所示:
此项表示提交表单后,指定的名称和值将自动包含在GET或POST数据中。每次Web浏览器发送回请求时,session_id值都可用于跟踪不同的Web浏览器。
这可能是跟踪会话的有效方法,但是单击常规的超文本链接(
URL重写
在标识该会话的每个URL的末尾附加一些额外的数据,并且服务器可以将该会话标识符与其已存储的有关该会话的数据相关联。
例如,对于http://tutorialspoint.com/file.htm;sessionid = 12345,会话标识符附加为sessionid = 12345,可以在Web服务器上访问该会话标识符以标识客户端。
URL重写是维护会话的一种更好的方法,即使浏览器不支持Cookie,它也可以工作。URL重写的缺点是,即使是简单的静态HTML页面,也必须动态生成每个URL才能分配会话ID。
HttpSession对象
除了上述三种方式之外,servlet还提供HttpSession接口,该接口提供了一种方法来跨多个页面请求标识用户或访问网站并存储有关该用户的信息。
Servlet容器使用此接口在HTTP客户端和HTTP服务器之间创建会话。该会话在用户的多个连接或页面请求中持续指定的时间段。
我们可以通过调用HttpServletRequest 的公共方法getSession()来获得HttpSession对象,如下所示:HttpSession session = request.getSession();
在将任何文档内容发送到客户端之前,需要调用request.getSession()。一下是HttpSession对象可用的重要方法的摘要:
方法 | 介绍 |
---|---|
public Object getAttribute(String name) | 在此会话中,此方法返回与指定名称绑定的对象;如果该名称下未绑定任何对象,则返回null。 |
public Enumeration getAttributeNames() | 此方法返回一个String对象的Enumeration,其中包含绑定到此会话的所有对象的名称。 |
public long getCreationTime() | 此方法返回创建此会话的时间,以格林尼治标准时间1970年1月1日午夜以来的毫秒数为单位。 |
public String getId() | 此方法返回一个字符串,其中包含分配给该会话的唯一标识符。 |
public long getLastAccessedTime() | 此方法返回会话的上次访问时间,格式为格林尼治标准时间1970年1月1日午夜以来的毫秒数。 |
public int getMaxInactiveInterval() | 此方法返回最大时间间隔(秒),servlet容器将使会话在客户端访问之间保持打开状态。 |
public void invalidate() | 此方法使该会话无效,并取消绑定到该会话的任何对象。 |
public boolean isNew() | 如果客户端尚不知道会话或客户端选择不加入会话,则此方法返回true。 |
public void removeAttribute(String name) | 此方法从此会话中删除与指定名称绑定的对象。 |
public void setAttribute(String name, Object value) | 此方法使用指定的名称将对象绑定到此会话。 |
public void setMaxInactiveInterval(int interval) | 此方法指定客户端请求之间servlet容器使该会话无效之前的时间(以秒为单位)。 |
示例
本示例说明如何使用HttpSession对象找出会话的创建时间和最后访问时间。如果一个新的会话尚不存在,我们将其与该请求相关联。
package servlet;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
public class SessionTrack extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//创建session
HttpSession session = request.getSession(true);
//获取session创建时间
Date createTime = new Date(session.getCreationTime());
//获取上次访问时间
Date lastAccessTime = new Date(session.getLastAccessedTime());
String title = "欢迎光临";
Integer visitCount = new Integer(0);
String visitCountKey ="visitCount";
String userIDKey = "userID";
String userID = "ABCD";
//检查是否第一次访问
if (session.isNew()) {
session.setAttribute(userIDKey, userID);
} else {
visitCount = (Integer)session.getAttribute(visitCountKey);
visitCount = visitCount + 1;
userID = (String)session.getAttribute(userIDKey);
}
session.setAttribute(visitCountKey, visitCount);
response.setHeader("contentType","text/html;charset=UTF-8");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
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信息</th><th>信息值</th>\n" +
"</tr>\n" +
"<tr>\n" +
" <td>id</td>\n" +
" <td>" + session.getId() + "</td>\n" +
"</tr>\n" +
"<tr>\n" +
" <td>创建时间</td>\n" +
" <td>" + createTime + " </td>\n" +
"</tr>\n" +
"<tr>\n" +
" <td>上一次访问时间</td>\n" +
" <td>" + lastAccessTime + " </td>\n" +
"</tr>\n" +
"<tr>\n" +
" <td>User ID</td>\n" +
" <td>" + userID + " </td>\n" +
"</tr>\n" +
"<tr>\n" +
" <td>访问次数</td>\n" +
" <td>" + visitCount + "</td>\n" +
"</tr>\n" +
"</table>\n" +
"</body>\n" +
"</html>"
);
}
}
编译上面的 SessionTrack Servlet并在web.xml文件中创建适当的条目。现在,当我们第一次运行http://localhost:8080/SessionTrack时,运行将显示以下结果:
现在尝试第二次运行相同的servlet,它将显示以下结果:
删除Session
完成用户的会话数据后,我们可以:
- 删除特定属性:调用public void removeAttribute(String name)方法来删除与特定键关联的值。
- 删除整个会话:调用public void invalidate()方法来丢弃整个会话。
- 设置会话超时:调用public void setMaxInactiveInterval(int interval)方法来分别设置会话超时。
- 注销用户:支持Servlet 2.4的服务器,调用logout将客户端从Web服务器注销
request.logout();
,并使属于所有用户的所有会话无效。 - web.xml配置:如果使用的是Tomcat,除了上述方法之外,还可以按以下方式在web.xml文件中配置会话超时。
<session-config>
<session-timeout>15</session-timeout>
</session-config>
`
其中的超时15以分钟为单位,并覆盖默认超时(在Tomcat中为30分钟)。
Servlet中的getMaxInactiveInterval()方法以秒为单位返回该会话的超时时间。因此,如果会话在web.xml中配置了15分钟,则getMaxInactiveInterval()返回900。
上一篇:[Servlet-Cookies处理](https://blog.csdn.net/JAVA_php_Jack/article/details/104255398)
下一篇[Servlet-文件上传](https://blog.csdn.net/JAVA_php_Jack/article/details/105161352)