Session

Session 概述

什么是 Session?Session 是一次浏览器和服务器的交互的会话。会话是啥呢?就是我问候你好吗?你回恩很好,就是一次会话,那么对话完成后,这次会话就结束了。

其含义是指:一类用来在客户端和服务器之间保持状态的解决方案。有时候 Session 也用来指这种解决方案的存储结构,如”把 xxx 保存在 session 里”。

Session 的工作原理

下面通过代码来说明 Session 的使用:

// 如果不存在 session 会话,则创建一个 session 对象
HttpSession session = request.getSession(true);Code language: JavaScript (javascript)

添加一个 Session 示例:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    response.getWriter().append("Served at: ").append(request.getContextPath());
    // 如果不存在 session 会话,则创建一个 session 对象
    HttpSession session = request.getSession(true);
    session.setAttribute("sitename", "foxdevelop");
    session.setAttribute("siteurl", "www.foxdevelop.com");
    session.setAttribute("currentlogin", "foxdevelop学员");
}Code language: JavaScript (javascript)

访问该 Servlet 时(如 http://localhost:8080/ServletDemo/session),会发现浏览器中多了一个名为 JSESSIONID 的 Cookie。这个 JSESSIONID 就是服务器用来通过 Cookie 识别每个用户 Session 的标识,这样才能区分每个客户端的 Session。例如换一个浏览器访问,该浏览器会获得一个新的 JSESSIONID

如果在同一个请求中再获取一个 Session:

HttpSession session2 = request.getSession(true);Code language: JavaScript (javascript)

再次访问时发现 JSESSIONID 仍然只有一个。实际上 sessionsession2 是同一个对象:

// 如果不存在 session 会话,则创建一个 session 对象
HttpSession session = request.getSession(true);
session.setAttribute("sitename", "foxdevelop");
session.setAttribute("siteurl", "www.foxdevelop.com");
session.setAttribute("currentlogin", "foxdevelop学员");

HttpSession session2 = request.getSession(true);
session2.setAttribute("sitename", "foxdevelop2");
System.out.println(session2.getAttribute("siteurl")); // 输出 www.foxdevelop.com,其实两个session都是同一个对象Code language: JavaScript (javascript)

Session 的存储结构可以这样描述:在客户端通过 JSESSIONID 来区别该客户端对应哪个 Session,然后服务器去内存中查找出该客户端的 Session,再通过 Session 的键来获取对应的值,一个 Session 中可以存储多个键值对。

Session 属性管理

移除 Session 中的属性

  • 移除一个特定的属性:调用 public void removeAttribute(String name) 方法删除与特定键相关联的值。
  • 删除整个 session 会话:调用 public void invalidate() 方法丢弃整个 session 会话。

设置 Session 超时时间

  • 代码方式:调用 public void setMaxInactiveInterval(int interval) 方法单独设置 session 会话超时(单位:秒)。
  • web.xml 配置:如果使用 Tomcat,除了上述方法,还可以在 web.xml 文件中配置 session 会话超时:
<session-config>
    <session-timeout>15</session-timeout>
</session-config>Code language: HTML, XML (xml)

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

综合操作示例

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    response.getWriter().append("Served at: ").append(request.getContextPath());
    // 如果不存在 session 会话,则创建一个 session 对象
    HttpSession session = request.getSession(true);
    session.setAttribute("sitename", "foxdevelop");
    session.setAttribute("siteurl", "www.foxdevelop.com");
    session.setAttribute("currentlogin", "foxdevelop学员");

    HttpSession session2 = request.getSession(true);
    session2.setAttribute("sitename", "foxdevelop2");
    System.out.println(session2.getAttribute("siteurl")); // 输出 www.foxdevelop.com,其实两个session都是同一个对象

    // 设置session的有效时间
    session.setMaxInactiveInterval(2 * 60); // 单位是秒,这里是2分钟

    // 移除attribute
    session.removeAttribute("siteurl");

    // 销毁session会话
    // session.invalidate();
}Code language: JavaScript (javascript)

Session 的读取

在其他 Servlet 中可以读取之前写入的 Session 数据:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    response.getWriter().append("Served at: ").append(request.getContextPath());
    Cookie[] cookies = request.getCookies();

    if (cookies != null && cookies.length > 0) {
        System.out.println(cookies[0].getValue());
    }
    HttpSession session = request.getSession(true);
    Object obj = session.getAttribute("sitename");
    String name = obj.toString();
    System.out.println(name);
    response.getWriter().append(name);
}Code language: JavaScript (javascript)

注意:如果之前调用了 session.invalidate() 销毁了会话,再次获取时将得到一个新的 Session 和新的 JSESSIONID。这也解释了为什么每次销毁后重新调用该 URL 会返回一个新的 JSESSIONID

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注