Skip to content

7.Session 跟踪

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

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

1. Cookies

一个 Web 服务器可以分配一个唯一的 session 会话 ID 作为每个 Web 客户端的 cookie,对于客户端的后续请求可以使用接收到的 cookie 来识别。

这可能不是一个有效的方法,因为很多浏览器不支持 cookie,所以我们建议不要使用这种方式来维持 session 会话。

2. 隐藏的表单字段

一个 Web 服务器可以发送一个隐藏的 HTML 表单字段,以及一个唯一的 session 会话 ID,如下所示:

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

3. URL 重写

您可以在每个 URL 末尾追加一些额外的数据来标识 session 会话,服务器会把该 session 会话标识符与已存储的有关 session 会话的数据相关联。

4. HttpSession 对象

除了上述的三种方式,Servlet 还提供了 HttpSession 接口。Servlet 容器使用这个接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。会话持续一个指定的时间段,跨多个连接或页面请求。

@WebServlet("/SessionTrack")
public class SessionTrack extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //没有session的话就新建一个
        HttpSession session = req.getSession(true);

        //访问次数计数器
        String count = "count";
        int num;

        if (session.isNew()){
            session.setAttribute(count, 1);
        }else {
            num = (int) session.getAttribute(count);
            num ++;
            session.setAttribute(count, num );
        }

        Date createTime = new Date(session.getCreationTime());
        Date lastTime = new Date(session.getLastAccessedTime());
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.write("<ul>\n");
        out.write("createTime: <li>" + formatter.format(createTime) + "</li>\n");
        out.write("lastTime: <li>" + formatter.format(lastTime) + "</li>\n");
        out.write("count: <li>" + session.getAttribute("count") + "</li>\n");
        out.write("</ul>\n");
    }
}

注意:你需要在向客户端发送任何文档内容之前调用 request.getSession()

5. 删除 Session 会话数据

当您完成了一个用户的 session 会话数据,您有以下几种选择:

  • 移除一个特定的属性:您可以调用 public void removeAttribute(String name) 方法来删除与特定的键相关联的值。
  • 删除整个 session 会话:您可以调用 public void invalidate() 方法来丢弃整个 session 会话。
  • 设置 session 会话过期时间:您可以调用 public void setMaxInactiveInterval(int interval) 方法来单独设置 session 会话超时。
  • 注销用户:如果使用的是支持 servlet 2.4 的服务器,您可以调用 logout 来注销 Web 服务器的客户端,并把属于所有用户的所有 session 会话设置为无效。
  • web.xml 配置:如果您使用的是 Tomcat,除了上述方法,您还可以在 web.xml 文件中配置 session 会话超时,如下所示:
  <session-config>
    <session-timeout>15</session-timeout>
  </session-config>

上面实例中的超时时间是以分钟为单位,将覆盖 Tomcat 中默认的 30 分钟超时时间。

在一个 Servlet 中的 getMaxInactiveInterval() 方法会返回 session 会话的超时时间,以秒为单位。所以,如果在 web.xml 中配置 session 会话超时时间为 15 分钟,那么 getMaxInactiveInterval() 会返回 900。