跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Java Web 开发实战:数据库操作与 Cookie Session 管理

介绍 Java Web 开发中的数据库操作与会话管理技术。涵盖 MySQL 基础操作(建库建表、增删改查)、JDBC 连接与使用(含 PreparedStatement 防注入)、数据库连接池(C3P0)配置及应用。同时详解 Cookie 与 Session 机制,通过 Servlet 示例演示会话数据的创建、读取与销毁,帮助开发者掌握用户状态管理及数据持久化方案。

片刻发布于 2026/4/6更新于 2026/7/2057 浏览
Java Web 开发实战:数据库操作与 Cookie Session 管理

四、Java Web 开发中的数据库操作:以 MySQL 为例

4.1 MySQL 数据库基础操作

MySQL 作为一种广泛使用的开源关系型数据库管理系统,在 Java Web 开发中扮演着举足轻重的数据存储与管理角色。理解并掌握 MySQL 的基础操作是进行 Java Web 数据库开发的基石。

数据库在 MySQL 中是数据存储与组织的核心容器,宛如一个大型的仓库,用于存放各类数据。创建数据库时,使用 CREATE DATABASE 语句,语法为 CREATE DATABASE [IF NOT EXISTS] database_name;。其中,IF NOT EXISTS 为可选参数,用于避免在数据库已存在时抛出错误。例如,创建一个名为 testdb 的数据库,代码如下:

CREATE DATABASE IF NOT EXISTS testdb;

若要切换当前操作的数据库,使用 USE 语句,如 USE testdb;,这就像是进入仓库的特定区域进行操作。查看所有数据库,可执行 SHOW DATABASES;,它会列出系统中所有的数据库,方便我们了解数据库的整体情况。而当某个数据库不再需要时,可使用 DROP DATABASE 语句删除,如 DROP DATABASE testdb;,但此操作需谨慎,因为一旦执行,数据库及其所有数据将被永久删除。

表是数据库中数据存储的具体结构,类似于仓库中的一个个货架,每个货架存放特定类型的数据。创建表时,需定义表名及各列的名称、数据类型和约束条件。例如,创建一个名为 users 的表,用于存储用户信息,包含 id(用户 ID,整数类型,自动递增且为主键)、username(用户名,可变长度字符串,最大长度为 50)、email(邮箱,可变长度字符串,最大长度为 100)和 password(密码,可变长度字符串,最大长度为 50),代码如下:

CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50), email VARCHAR(100), password VARCHAR(50) );

查看数据库中的所有表,执行 SHOW TABLES;,它会展示当前数据库中所有的表名。若要查看某个表的结构,使用 DESCRIBE 语句,如 DESCRIBE users;,它会详细列出表中各列的信息,包括列名、数据类型、是否允许为空等,帮助我们了解表的设计。当表不再需要时,使用 DROP TABLE 语句删除,如 DROP TABLE users;,同样,此操作会删除表及其所有数据,需谨慎使用。

在数据库中插入数据是常见操作,向 users 表中插入一条用户数据,包含用户名 john_doe、邮箱 [email protected] 和密码 password123,代码如下:

INSERT INTO users (username, email, password) VALUES ('john_doe', '[email protected]', 'password123');

若要插入多条数据,可在 VALUES 关键字后用逗号分隔多个值列表,如:

 users (username, email, password)  (, , ), (, , );
INSERT INTO
VALUES
'jane_smith'
'[email protected]'
'password456'
'tom_wilson'
'[email protected]'
'password789'

从数据库中查询数据是获取信息的关键操作。查询 users 表中所有用户的信息,使用 SELECT 语句,代码如下:

SELECT * FROM users;

这里的 * 表示选择所有列。若只查询部分列,如只查询 username 和 email 列,代码为:

SELECT username, email FROM users;

若要根据条件查询,如查询用户名为 john_doe 的用户信息,使用 WHERE 子句,代码如下:

SELECT * FROM users WHERE username = 'john_doe';

还可以对查询结果进行排序,如按 username 升序排序,代码为:

SELECT * FROM users ORDER BY username ASC;

ASC 表示升序,DESC 表示降序。

更新数据库中的数据用于修改现有记录。将 users 表中用户名为 john_doe 的用户邮箱更新为 [email protected],代码如下:

UPDATE users SET email = '[email protected]' WHERE username = 'john_doe';

删除数据库中的数据用于移除不再需要的记录。删除 users 表中用户名为 tom_wilson 的用户记录,代码如下:

DELETE FROM users WHERE username = 'tom_wilson';

4.2 JDBC 技术深度解析

JDBC(Java Database Connectivity)是 Java 语言中用于连接和操作数据库的重要 API,它为 Java 开发者提供了一种统一的方式来与各种不同类型的数据库进行交互,使得 Java 应用程序能够方便地访问和管理数据库中的数据,就像一座桥梁,连接着 Java 程序与数据库。

JDBC 的核心接口和常用类构成了其强大功能的基础。DriverManager 类是 JDBC 的管理层,负责管理数据库驱动程序的加载和建立数据库连接。它就像是一个交通枢纽管理员,协调着 Java 程序与不同数据库之间的连接。例如,在加载 MySQL 数据库驱动时,使用 Class.forName("com.mysql.cj.jdbc.Driver"); 语句,告知 DriverManager 要使用的数据库驱动类。

Connection 接口代表与数据库的连接,它是与数据库交互的基础。通过 DriverManager.getConnection(url, username, password) 方法获取连接对象,其中 url 为数据库连接字符串,username 和 password 分别为数据库的用户名和密码。例如:

String url = "jdbc:mysql://localhost:3306/testdb";
String username = "root";
String password = "password";
Connection connection = DriverManager.getConnection(url, username, password);

Statement 接口用于执行 SQL 语句,它可以直接执行静态 SQL 语句。通过 Connection 对象的 createStatement() 方法创建 Statement 对象,如 Statement statement = connection.createStatement();。然后使用 statement.executeQuery(sql) 方法执行查询语句,返回 ResultSet 结果集;使用 statement.executeUpdate(sql) 方法执行插入、更新、删除等语句,返回受影响的行数。

PreparedStatement 接口继承自 Statement 接口,它主要用于执行预编译的 SQL 语句。预编译的 SQL 语句可以提高执行效率,并且能有效防止 SQL 注入攻击。通过 Connection 对象的 prepareStatement(sql) 方法创建 PreparedStatement 对象,其中 sql 为带有参数占位符(?)的 SQL 语句。例如,插入用户数据的预编译 SQL 语句为:

String sql = "INSERT INTO users (username, email, password) VALUES (?,?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, "new_user");
preparedStatement.setString(2, "[email protected]");
preparedStatement.setString(3, "new_password");
int rowsAffected = preparedStatement.executeUpdate();

ResultSet 接口用于存储查询结果集,它提供了一系列方法来遍历和获取结果集中的数据。通过 Statement 或 PreparedStatement 执行查询语句后返回 ResultSet 对象,然后使用 while (resultSet.next()) 循环遍历结果集,通过 resultSet.getString("column_name") 等方法获取指定列的值。例如:

String sql = "SELECT * FROM users";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
    int id = resultSet.getInt("id");
    String username = resultSet.getString("username");
    String email = resultSet.getString("email");
    System.out.println("ID: " + id + ", Username: " + username + ", Email: " + email);
}

接下来,我们通过一个完整的代码示例来展示如何使用 JDBC 连接 MySQL 数据库并执行查询操作:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JdbcExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/testdb";
        String username = "root";
        String password = "password";
        try {
            // 加载驱动程序
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 获取连接
            Connection connection = DriverManager.getConnection(url, username, password);
            // 创建 Statement 对象
            Statement statement = connection.createStatement();
            // 执行查询语句
            String sql = "SELECT * FROM users";
            ResultSet resultSet = statement.executeQuery(sql);
            // 处理结果集
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String usernameFromDb = resultSet.getString("username");
                String email = resultSet.getString("email");
                System.out.println("ID: " + id + ", Username: " + usernameFromDb + ", Email: " + email);
            }
            // 关闭资源
            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,首先加载 MySQL 驱动程序,然后通过 DriverManager 获取与数据库的连接。接着创建 Statement 对象,执行查询语句并获取结果集。最后,通过循环遍历结果集,输出查询到的用户信息。操作完成后,依次关闭 ResultSet、Statement 和 Connection 对象,以释放资源。

在使用 JDBC 过程中,可能会遇到一些常见问题。例如,驱动程序未找到异常 ClassNotFoundException,这通常是因为没有正确添加数据库驱动包或驱动类名写错。解决方法是确保数据库驱动包已正确添加到项目的类路径中,并检查驱动类名是否正确。

还有连接数据库失败的问题,可能是由于连接字符串错误、用户名或密码错误、数据库服务器未启动等原因导致。此时需要仔细检查连接字符串、用户名和密码,确保数据库服务器处于运行状态。

SQL 注入攻击也是一个需要关注的问题,如用户输入的数据被恶意拼接在 SQL 语句中,可能导致数据泄露或数据被篡改。使用 PreparedStatement 代替 Statement 可以有效防止 SQL 注入攻击,因为 PreparedStatement 会对参数进行预处理,避免了直接将用户输入的数据拼接到 SQL 语句中。

4.3 数据库连接池的应用

在 Java Web 开发中,频繁地创建和销毁数据库连接会带来显著的性能开销,因为建立数据库连接涉及网络通信、数据库认证等复杂操作,耗费时间和资源。数据库连接池技术应运而生,它通过预先创建一定数量的数据库连接,并将这些连接存储在连接池中,当应用程序需要与数据库进行交互时,可以直接从连接池中获取一个可用的连接,而不需要每次都重新建立连接。使用完成后,连接会被返回到连接池中,以便后续使用。这种方式大大减少了连接的建立和销毁的开销,提高了系统的性能和响应速度,就像一个连接的'仓库',随时为应用程序提供可用的连接。

常见的数据库连接池有 HikariCP、C3P0、DBCP 等。HikariCP 以其高性能和低延迟著称,具有快速的连接获取速度、低资源消耗和高并发性能等特点,适用于高并发、高性能需求的应用程序。C3P0 是一个老牌的 Java 数据库连接池,具有较高的稳定性和可靠性,支持自动回收连接、测试连接的有效性等功能,还提供了多种配置选项,用户可以根据具体需求进行灵活配置。DBCP 是 Apache Commons 项目的一部分,具有简单易用、配置灵活等特点,支持连接池的基本功能,如连接回收、连接测试等,同时还提供了一些高级功能,如连接的统计信息、自动重连等。

接下来,我们以 C3P0 为例,展示如何配置和使用数据库连接池。首先,需要在项目中添加 C3P0 的依赖。如果使用 Maven 项目,在 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.5</version>
</dependency>

然后,在 src 目录下创建 c3p0-config.xml 配置文件,进行连接池的配置,示例代码如下:

<c3p0-config>
    <default-config>
        <!-- 数据库驱动名 -->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <!-- 数据库的 url -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/testdb</property>
        <!-- 用户名 -->
        <property name="user">root</property>
        <!-- 密码 -->
        <property name="password">password</property>
        <!-- 当连接池中的连接耗尽的时候 c3p0 一次同时获取的连接数。Default:3 -->
        <property name="acquireIncrement">5</property>
        <!-- 初始化数据库连接池时连接的数量 -->
        <property name="initialPoolSize">5</property>
        <!-- 数据库连接池中的最小的数据库连接数 -->
        <property name="minPoolSize">5</property>
        <!-- 数据库连接池中的最大的数据库连接数 -->
        <property name="maxPoolSize">10</property>
        <!-- 连接关闭时默认将所有未提交的操作回滚。Default: false -->
        <property name="autoCommitOnClose">false</property>
        <!-- 每 60 秒检查所有连接池中的空闲连接。Default:0 -->
        <property name="idleConnectionTestPeriod">60</property>
        <!-- 最大空闲时间,指定的时间内未使用则连接被丢弃。若为 0 则永不丢弃。Default:0 -->
        <property name="maxIdleTime">300</property>
    </default-config>
</c3p0-config>

在上述配置文件中,设置了数据库驱动类、连接 URL、用户名、密码等基本信息,还配置了连接池的一些属性,如初始连接数、最小连接数、最大连接数、获取连接失败后的重试策略等。

接下来,通过代码获取连接池中的连接并执行数据库操作,示例代码如下:

import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class C3P0Example {
    public static void main(String[] args) {
        // 创建 C3P0 数据源
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        try {
            // 配置数据源属性(也可通过 c3p0-config.xml 配置)
            dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/testdb");
            dataSource.setUser("root");
            dataSource.setPassword("password");
            // 配置连接池属性(也可通过 c3p0-config.xml 配置)
            dataSource.setMinPoolSize(5);
            dataSource.setMaxPoolSize(10);
            dataSource.setCheckoutTimeout(3000);
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;
            try {
                // 从连接池获取连接
                connection = dataSource.getConnection();
                // 执行查询
                String sql = "SELECT * FROM users";
                preparedStatement = connection.prepareStatement(sql);
                resultSet = preparedStatement.executeQuery();
                // 处理查询结果
                while (resultSet.next()) {
                    int id = resultSet.getInt("id");
                    String username = resultSet.getString("username");
                    String email = resultSet.getString("email");
                    System.out.println("ID: " + id + ", Username: " + username + ", Email: " + email);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            } finally {
                // 释放资源
                if (resultSet != null) {
                    try { resultSet.close(); } catch (SQLException ex) { ex.printStackTrace(); }
                }
                if (preparedStatement != null) {
                    try { preparedStatement.close(); } catch (SQLException ex) { ex.printStackTrace(); }
                }
                if (connection != null) {
                    try { connection.close(); // 将连接放回连接池 } catch (SQLException ex) { ex.printStackTrace(); }
                }
            }
        } catch (PropertyVetoException ex) {
            ex.printStackTrace();
        } finally {
            // 关闭数据源(通常在应用程序关闭时执行)
            dataSource.close();
        }
    }
}

五、Java Web 中的会话技术:Cookie 与 Session

5.1 Cookie 详解

Cookie 是一种客户端会话管理技术,它就像是服务器发给客户端浏览器的一张小纸条,用于在客户端存储少量数据。当用户访问服务器时,服务器可以将一些信息以 Cookie 的形式发送给浏览器,浏览器会将这些 Cookie 存储在本地。当下次用户再次访问服务器时,浏览器会自动将这些 Cookie 发送给服务器,服务器可以根据这些 Cookie 来识别用户的身份或获取相关的用户信息。

Cookie 的主要作用包括:

  • 会话状态管理:例如用户登录信息的记录,当用户登录成功后,服务器可以将用户的登录状态以 Cookie 的形式发送给浏览器,下次用户访问时,服务器可以通过 Cookie 判断用户是否已经登录,从而决定是否需要用户再次登录。
  • 个性化设置:存储用户的个性化设置,如用户在网站上设置的语言偏好、主题风格等,服务器可以根据 Cookie 中的设置为用户提供个性化的服务。
  • 购物车功能:在电商网站中,Cookie 可以用于存储用户购物车中的商品信息,方便用户在不同页面之间切换时,购物车中的商品信息不会丢失。

在 Java 中,操作 Cookie 主要使用 javax.servlet.http.Cookie 类。常用的属性和方法如下:

属性:

  • name:Cookie 的名称,用于标识 Cookie,名称必须唯一。
  • value:Cookie 的值,用于存储具体的数据。
  • maxAge:Cookie 的最大生存时间,以秒为单位。如果设置为正数,Cookie 会在指定的时间后过期;如果设置为负数,Cookie 会在浏览器关闭时过期(默认情况);如果设置为 0,则会立即删除该 Cookie。
  • path:Cookie 的路径,指定 Cookie 在哪些路径下有效。例如,如果设置为/app,则只有访问/app或其子路径(如/app/products)的请求才会携带该 Cookie;如果设置为/,则整个网站的所有路径下的请求都会携带该 Cookie。
  • domain:Cookie 的域名,指定 Cookie 在哪个域名下有效。默认情况下,Cookie 只在创建它的域名下有效;如果设置为一级域名(如.example.com),则该域名及其所有子域名(如 www.example.com、api.example.com)下的请求都可以访问该 Cookie。
  • secure:是否仅通过 HTTPS 连接传输 Cookie。如果设置为 true,则只有在使用 HTTPS 协议访问时,浏览器才会将该 Cookie 发送给服务器,以提高 Cookie 在传输过程中的安全性;如果设置为 false(默认值),则 HTTP 和 HTTPS 连接都可以传输 Cookie。
  • httpOnly:是否只能通过 HTTP (S) 请求访问 Cookie。如果设置为 true,则 JavaScript 代码无法读取或修改该 Cookie,从而增强了 Cookie 的安全性,防止 Cookie 被 JavaScript 脚本窃取或篡改;如果设置为 false(默认值),则 JavaScript 代码可以访问 Cookie。

常用方法:

  • Cookie(String name, String value):构造方法,用于创建一个 Cookie 对象,传入 Cookie 的名称和值。
  • void setMaxAge(int expiry):设置 Cookie 的最大生存时间,单位为秒。
  • String getName():获取 Cookie 的名称。
  • String getValue():获取 Cookie 的值。
  • void setValue(String value):设置 Cookie 的值。
  • void setPath(String path):设置 Cookie 的路径。
  • void setDomain(String domain):设置 Cookie 的域名。
  • void setSecure(boolean flag):设置是否仅通过 HTTPS 连接传输 Cookie。
  • void setHttpOnly(boolean flag):设置是否只能通过 HTTP (S) 请求访问 Cookie。

下面通过代码示例来展示如何创建、发送和获取 Cookie:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/cookieExample")
public class CookieExampleServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 创建一个 Cookie 对象,名称为 username,值为 John
        Cookie cookie = new Cookie("username", "John");
        // 设置 Cookie 的最大生存时间为 1 小时(3600 秒)
        cookie.setMaxAge(3600);
        // 设置 Cookie 的路径为根路径
        cookie.setPath("/");
        // 将 Cookie 添加到响应中,发送给客户端
        response.addCookie(cookie);
        response.getWriter().println("Cookie has been set.");
    }

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

上述代码创建了一个名为 username,值为 John 的 Cookie,并设置了它的最大生存时间为 1 小时,路径为根路径,然后将其添加到响应中发送给客户端。

在另一个 Servlet 中获取 Cookie 的代码如下:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/getCookieExample")
public class GetCookieExampleServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取客户端发送的所有 Cookie
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                // 找到名为 username 的 Cookie
                if ("username".equals(cookie.getName())) {
                    String username = cookie.getValue();
                    response.getWriter().println("Username from Cookie: " + username);
                    break;
                }
            }
        }
    }

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

这段代码从客户端请求中获取所有的 Cookie,并遍历查找名为 username 的 Cookie,如果找到则输出其值。

需要注意的是,在设置 Cookie 的路径时,要根据实际需求进行设置。如果路径设置不当,可能会导致 Cookie 无法在预期的页面中被发送或接收。例如,如果一个 Cookie 的路径设置为/app,那么在访问根路径(/)下的页面时,该 Cookie 不会被发送;只有在访问/app或其子路径下的页面时,该 Cookie 才会被发送。此外,Cookie 的大小有限制,每个 Cookie 通常不能超过 4KB,并且浏览器对同一个域名下的 Cookie 数量也有限制,一般最多为 20 个左右,在使用 Cookie 时要考虑这些限制因素。

5.2 Session 详解

Session 是一种服务端会话管理技术,它为每个用户的浏览器创建一个独享的会话空间,用于在服务器端存储用户的会话数据。当用户访问服务器时,服务器会为其创建一个 Session 对象,并分配一个唯一的 Session ID。这个 Session ID 通常会通过 Cookie 发送给客户端浏览器,浏览器在后续的请求中会将这个 Session ID 发送回服务器,服务器根据这个 Session ID 来识别用户的会话,并获取该用户在 Session 中存储的数据。

Session 的工作原理如下:

  1. 用户首次访问服务器时,服务器会创建一个新的 Session 对象,并生成一个唯一的 Session ID。
  2. 服务器将 Session ID 通过 Cookie 发送给客户端浏览器,这个 Cookie 的名称通常为 JSESSIONID。
  3. 客户端浏览器在后续的请求中,会将包含 JSESSIONID 的 Cookie 发送回服务器。
  4. 服务器接收到请求后,根据 Cookie 中的 JSESSIONID 找到对应的 Session 对象,从而获取该用户的会话数据。

Session 的主要作用是在一次会话中,为用户提供一个可以在不同页面或请求之间共享数据的空间。例如,在一个电商网站中,用户在浏览商品时将商品添加到购物车,这些购物车中的商品信息就可以存储在 Session 中。当用户跳转到结算页面时,服务器可以从 Session 中获取购物车信息,展示给用户并进行结算操作。

在 Java 中,操作 Session 主要通过 HttpSession 接口。常用的方法如下:

  • HttpSession getSession():获取当前请求的 Session 对象。如果当前请求没有 Session 对象,则会创建一个新的 Session 对象。
  • HttpSession getSession(boolean create):获取当前请求的 Session 对象。如果 create 参数为 true,且当前请求没有 Session 对象,则会创建一个新的 Session 对象;如果 create 参数为 false,且当前请求没有 Session 对象,则返回 null。
  • void setAttribute(String name, Object value):在 Session 中存储一个属性,属性名为 name,属性值为 value。
  • Object getAttribute(String name):从 Session 中获取指定属性名的属性值。如果属性不存在,则返回 null。
  • void removeAttribute(String name):从 Session 中移除指定属性名的属性。
  • String getId():获取 Session 的唯一标识符(Session ID)。
  • long getCreationTime():获取 Session 的创建时间,返回值为自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数。
  • long getLastAccessedTime():获取客户端最后一次访问该 Session 的时间,返回值为自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数。
  • void setMaxInactiveInterval(int interval):设置 Session 的最大非活动间隔时间,单位为秒。如果在这个时间内客户端没有访问该 Session,则 Session 会被销毁。
  • int getMaxInactiveInterval():获取 Session 的最大非活动间隔时间,单位为秒。
  • void invalidate():使当前 Session 失效,即销毁 Session 对象及其存储的所有属性。

下面通过代码示例来展示如何创建、获取和销毁 Session,以及在 Session 中保存和获取数据:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/sessionExample")
public class SessionExampleServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取当前请求的 Session 对象,如果不存在则创建一个新的
        HttpSession session = request.getSession();
        // 在 Session 中保存一个属性,名称为 username,值为 John
        session.setAttribute("username", "John");
        // 获取 Session 的 ID
        String sessionId = session.getId();
        response.getWriter().println("Session ID: " + sessionId);
        response.getWriter().println("Username saved in Session: " + session.getAttribute("username"));
        // 设置 Session 的最大非活动间隔时间为 30 分钟(1800 秒)
        session.setMaxInactiveInterval(1800);
    }

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

上述代码获取当前请求的 Session 对象,在 Session 中保存了一个名为 username,值为 John 的属性,并输出了 Session ID 和保存的用户名。同时,设置了 Session 的最大非活动间隔时间为 30 分钟。

在另一个 Servlet 中获取 Session 数据的代码如下:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/getSessionExample")
public class GetSessionExampleServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取当前请求的 Session 对象(如果不存在则不创建)
        HttpSession session = request.getSession(false);
        if (session != null) {
            // 从 Session 中获取名为 username 的属性值
            String username = (String) session.getAttribute("username");
            response.getWriter().println("Username from Session: " + username);
        } else {
            response.getWriter().println("Session does not exist.");
        }
    }

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

这段代码获取当前请求的 Session 对象(如果不存在则不创建),并从 Session 中获取名为 username 的属性值进行输出。

销毁 Session 的代码如下:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/destroySessionExample")
public class DestroySessionExampleServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取当前请求的 Session 对象(如果不存在则不创建)
        HttpSession session = request.getSession(false);
        if (session != null) {
            // 使 Session 失效,即销毁 Session
            session.invalidate();
            response.getWriter().println("Session has been destroyed.");
        } else {
            response.getWriter().println("Session does not exist.");
        }
    }

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

这段代码获取当前请求的 Session 对象(如果不存在则不创建),并调用 invalidate 方法使 Session 失效,即销毁 Session 及其存储的所有属性。

Session 与 Cookie 有着密切的关系,Session 的实现依赖于 Cookie 来传递 Session ID。如果客户端禁用了 Cookie,那么 Session ID 就无法通过 Cookie 发送回服务器,服务器也就无法识别用户的会话。为了解决这个问题,可以采用 URL 重写的方式,将 Session ID 附加在 URL 后面进行传递。例如,原本的 URL 为 http://example.com/page,经过 URL 重写后变为 http://example.com/page;jsessionid=1234567890,这样服务器仍然可以根据 URL 中的 Session ID 来识别用户的会话。不过,这种方式存在一定的安全风险,因为 Session ID 暴露在 URL 中,可能会被恶意用户窃取和利用,所以在实际应用中,应尽量确保客户端启用 Cookie 来传递 Session ID,以提高系统的安全性。

目录

  1. 四、Java Web 开发中的数据库操作:以 MySQL 为例
  2. 4.1 MySQL 数据库基础操作
  3. 4.2 JDBC 技术深度解析
  4. 4.3 数据库连接池的应用
  5. 五、Java Web 中的会话技术:Cookie 与 Session
  6. 5.1 Cookie 详解
  7. 5.2 Session 详解
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Seedance 2.0 智能资源画像与 Terraform 算力预算方案实践
  • 二叉树前中后序遍历详解:递归与迭代实现
  • Linux 进程详解:从基础概念到实战操作
  • JetBrains Copilot Agent Mode + MCP 配置与实战指南
  • ClawdBot (OpenClaw) Discord 机器人部署指南
  • WebGPU 性能调优技术解析与实践
  • Spring Boot 安全认证与授权
  • OpenClaw 接入 QQ 机器人配置指南
  • Stable Diffusion 本地部署与安装教程
  • 考公压力大是否该放弃?程序员职业路径的理性思考
  • 网络安全零基础入门指南:学习误区、路线与自学利弊分析
  • Spatial Joy 2025 全球 AR&AI 开发大赛参赛指南与避坑攻略
  • Java AI 开发实战:从代码生成到架构优化指南
  • 基于 AirLLM 实现 4GB 显存环境下的 Qwen2.5-72B 本地推理
  • Python3 实用安装教程
  • Microi 吾码:服务器虚拟化资源管理与网络配置实践
  • OpenClaw 深度解析:数字龙虾如何引爆 AI Agent 时代与安全挑战
  • Spring 事务管理实战:@Transactional 注解与传播机制深度解析
  • Model Context Protocol (MCP) 详解:连接 AI 模型与外部工具的新标准
  • Python 爬虫基础教程:请求、解析与数据存储

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online