杰瑞科技汇

Java session如何高效存取?

什么是 Session?

Session(会话) 是一种在 Web 服务器上记录用户状态的技术,它的工作原理如下:

Java session如何高效存取?-图1
(图片来源网络,侵删)
  1. 用户访问:当一个用户首次访问一个网站时,服务器会为其创建一个独一无二的 Session 对象。
  2. 分配 ID:服务器会给这个 Session 对象分配一个唯一的 ID,称为 SessionID
  3. 传递 ID:服务器通过一个名为 JSESSIONID 的 Cookie 将这个 SessionID 发送给客户端的浏览器,并保存在浏览器中。
  4. 后续请求:当该用户再次访问同一个网站的任何页面时,浏览器会自动携带这个 JSESSIONID Cookie。
  5. 服务器识别:服务器接收到请求后,会读取 JSESSIONID,然后根据这个 ID 找到之前为该用户创建的 Session 对象,从而实现跨页面的状态保持。

Session 就像一个服务器端的“购物车”,每个用户都有自己的专属购物车,通过 SessionID 这个“钥匙”来打开自己的购物车。


如何在 Java 中存取 Session?(Servlet API)

在标准的 Java Web 开发中(使用 Servlet),我们可以通过 HttpServletRequestHttpSession 对象来操作 Session。

获取 Session 对象

在 Servlet 的 doGetdoPost 方法中,通过 request.getSession() 方法来获取当前用户的 Session 对象。

  • request.getSession(): 如果当前请求没有关联的 Session,此方法会创建一个新的 Session并返回,这是最常用的方式。
  • request.getSession(false): 如果当前请求没有关联的 Session,此方法不会创建新的 Session,而是返回 null,当你只想在有 Session 的情况下操作时,可以使用这个方法。
// 在 Servlet 的 service 方法中
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 获取 Session,如果不存在则创建一个新的
    HttpSession session = request.getSession();
    // 或者:如果不存在则不创建,返回 null
    // HttpSession session = request.getSession(false);
}

向 Session 中存入数据(setAttribute)

获取到 HttpSession 对象后,我们可以使用 setAttribute(String name, Object value) 方法来存入数据。

Java session如何高效存取?-图2
(图片来源网络,侵删)
  • name: 一个字符串,作为数据的键。
  • value: 一个 Java 对象,作为值,注意:Session 中存储的对象必须是可序列化的(implements Serializable),因为服务器可能会在内存不足时将其序列化到硬盘上。

示例:

假设我们有一个登录功能,登录成功后将用户信息存入 Session。

// LoginServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    // 假设验证成功
    if ("admin".equals(username) && "password".equals(password)) {
        // 1. 获取 Session
        HttpSession session = request.getSession();
        // 2. 创建一个用户对象 (假设 User 类已定义)
        User user = new User(username, "admin@example.com");
        // 3. 将用户对象存入 Session
        // 键为 "user",值为 user 对象
        session.setAttribute("user", user);
        // 也可以存入简单的字符串
        session.setAttribute("loginTime", new Date().toString());
        // 重定向到主页
        response.sendRedirect("home.jsp");
    } else {
        // 登录失败,返回登录页面
        response.sendRedirect("login.jsp?error=1");
    }
}

从 Session 中读取数据(getAttribute)

使用 getAttribute(String name) 方法可以从 Session 中读取数据。

  • name: 你之前存入数据时使用的键。
  • 返回值Object 类型,你需要将其强制类型转换为你当初存入时的对象类型。
  • 注意:如果指定的键不存在,此方法会返回 null,而不是抛出异常。

示例:

Java session如何高效存取?-图3
(图片来源网络,侵删)

在主页 home.jsp 或另一个 Servlet 中获取并显示用户信息。

// HomeServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1. 获取 Session
    HttpSession session = request.getSession();
    // 2. 从 Session 中获取用户对象
    // 需要将 Object 强制转换为 User 类型
    User user = (User) session.getAttribute("user");
    // 3. 判断 user 是否为 null(即用户是否已登录)
    if (user != null) {
        // 用户已登录,显示欢迎信息
        request.setAttribute("welcomeMsg", "欢迎, " + user.getUsername() + "!");
        request.getRequestDispatcher("/home.jsp").forward(request, response);
    } else {
        // 用户未登录,重定向到登录页面
        response.sendRedirect("login.jsp");
    }
}

从 Session 中移除数据(removeAttribute)

当用户注销或者某些数据不再需要时,应该及时从 Session 中移除,以节省服务器内存。

使用 removeAttribute(String name) 方法。

示例:

在注销 Servlet 中移除用户信息。

// LogoutServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1. 获取 Session
    HttpSession session = request.getSession();
    // 2. 移除 Session 中的用户信息
    session.removeAttribute("user");
    session.removeAttribute("loginTime");
    // 3. 可选:使整个 Session 失效(销毁整个 Session 对象)
    // session.invalidate();
    // 重定向到登录页面
    response.sendRedirect("login.jsp");
}

JSP 中的 Session 存取

在 JSP 页面中,Session 对象是内置对象之一,可以直接使用,无需获取。

存入数据

使用 JSP 的内置脚本或 EL 表达式。

<%-- 使用 JSP 脚本 --%>
<%
    User user = new User("zhangsan", "zhangsan@example.com");
    session.setAttribute("user", user); // 直接使用 session 对象
%>
<%-- 使用 EL 表达式 (更推荐) --%>
<%-- EL 表达式主要用于读取,但也可以配合 JSTL 的 <c:set> 来设置 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="user" value="${new com.example.User('lisi', 'lisi@example.com')}" scope="session" />

读取数据

使用 EL 表达式是读取 Session 数据最简洁、最推荐的方式。

<%-- 使用 EL 表达式读取 --%>
<p>当前登录用户: ${sessionScope.user.username}</p>
<p>登录时间: ${sessionScope.loginTime}</p>
<%-- 也可以直接使用 ${user},因为 EL 会按 page -> request -> session -> application 的顺序查找 --%>
<p>简化写法: ${user.username}</p>

移除数据

同样可以使用 JSTL 的核心标签库。

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:remove var="user" scope="session" />
<c:remove var="loginTime" scope="session" />

Session 的生命周期和配置

  1. 创建时机:第一次调用 request.getSession() 时。
  2. 销毁时机
    • 超时:如果一段时间内(30 分钟)用户没有发送任何请求,Session 会自动失效,超时时间可以在 web.xml 中配置。
      <web-app>
        <session-config>
          <session-timeout>30</session-timeout> <!-- 单位:分钟 -->
        </session-config>
      </web-app>
    • 手动销毁:调用 session.invalidate()
    • 服务器关闭或重启:所有 Session 都会被销毁。
  3. Cookie 禁用问题:如果用户禁用了浏览器的 Cookie,JSESSIONID 无法传递,Session 机制就会失效,解决方案是 URL 重写,即把 SessionID 直接附加在 URL 后面,Servlet 容器会自动处理,你只需要确保所有链接都使用 response.encodeURL()response.encodeRedirectURL() 方法包装即可。
操作 Servlet API JSP (内置对象)
获取 Session request.getSession() 直接使用 session
存入数据 session.setAttribute("key", value) <c:set var="key" value="value" scope="session" />
读取数据 Object obj = session.getAttribute("key"); ${sessionScope.key}${key}
移除数据 session.removeAttribute("key") <c:remove var="key" scope="session" />
销毁 Session session.invalidate() 无直接对应,可通过 Servlet 调用

理解 Session 的存取机制是进行 Web 应用开发的基础,它解决了 HTTP 协议无状态的核心问题,是实现用户登录、购物车、个性化设置等功能的基石。

分享:
扫描分享到社交APP
上一篇
下一篇