一、项目整体流程,「Servlet 封装集合数据 → Request 域传递 → JSP+JSTL 遍历展示」

  • 编写 person 实体类,封装人员信息;
  • 编写 PersonServlet,创建人员集合并传递到 JSP;
  • 编写 person.jsp,用 JSTL 遍历并展示人员列表;
  • (可选)准备数据库脚本,后续可拓展为从数据库读取数据。

1、步骤 1:创建 person 实体类

首先我们需要一个实体类来封装人员的属性,包括学号、姓名、年龄、身高、联系方式。

public class person {
    // 私有属性
    private int id;
    private String name;
    private int age;
    private float height;
    private String phone;

    // 无参构造方法(JSTL操作对象必须有)
    public person() {}

    // 全参构造方法(快速创建对象)
    public person(int id, String name, int age, float height, String phone) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.height = height;
        this.phone = phone;
    }

    // Getter 和 Setter 方法(JSTL访问属性必须有)
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }

    public float getHeight() { return height; }
    public void setHeight(float height) { this.height = height; }

    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }
}

    注意

    • 实体类必须提供无参构造方法,否则 JSTL 无法创建对象;
    • 每个属性都要有对应的 gettersetter 方法,JSTL 会自动调用 getter 获取属性值。

    2、步骤 2:编写 PersonServlet 后端控制器

    Servlet 是我们的后端控制器,负责创建人员集合,存入 request 域,再转发到 JSP 页面。

    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 java.io.IOException;
    import java.util.ArrayList;
    
    // 配置Servlet访问路径,必须和前端访问地址一致
    @WebServlet("/persons")
    public class PersonServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 1. 创建ArrayList集合,存储person对象
            ArrayList<person> personArrayList = new ArrayList<>();
    
            // 2. 向集合中添加人员数据
            personArrayList.add(new person(1, "张三", 18, 160, "1111111111111"));
            personArrayList.add(new person(2, "李四", 20, 150, "2222222222222"));
            personArrayList.add(new person(3, "王五", 17, 155, "3333333333333"));
            personArrayList.add(new person(4, "刘六", 19, 156, "4444444444444"));
            personArrayList.add(new person(5, "赵二", 21, 165, "5555555555555"));
    
            // 3. 将集合存入request域,key为"persons",供JSP获取
            req.setAttribute("persons", personArrayList);
    
            // 4. 请求转发到JSP页面(服务器内部跳转,request数据不会丢失)
            req.getRequestDispatcher("/javabean2/person.jsp").forward(req, resp);
        }
    }

    关键知识点解析

    • @WebServlet("/persons"):配置 Servlet 的访问路径,浏览器访问 http://localhost:8080/项目名/persons 即可触发;
    • ArrayList<person>:用泛型限定集合只能存储 person 对象,避免数据混乱;
    • req.setAttribute("persons", personArrayList):把集合存入 request 域,数据会随着请求转发传递到 JSP;
    • forward(req, resp):服务器内部跳转,地址栏不会变化,request 域中的数据会保留。

    3、步骤 3:编写 person.jsp 前端展示页面

    JSP 页面负责接收后端传递的集合数据,并用 JSTL 标签遍历展示。

    <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>人员列表</title>
    </head>
    <body>
        <%-- 遍历request域中的persons集合 --%>
        <c:forEach var="person" items="${persons}" varStatus="status">
            学号:<c:out value="${person.id}" />
            姓名:<c:out value="${person.name}"/>
            年龄:<c:out value="${person.age}"/>
            身高:<c:out value="${person.height}"/>
            联系方式:<c:out value="${person.phone}"/>
            <br>
        </c:forEach>
    </body>
    </html>

    关键知识点解析

    • <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>:引入 JSTL 核心标签库,才能使用 <c:forEach><c:out> 标签;
    • <c:forEach items="${persons}" var="person">:遍历 request 域中的 persons 集合,每次循环将当前元素存入 person 变量;
    • <c:out value="${person.id}" />:安全输出 person 对象的属性值,比直接 EL 表达式更安全,支持默认值。

    4、数据库脚本

    项目后续可以拓展为从 MySQL 数据库读取数据,以下是创建数据库和用户表的 SQL 脚本:

    -- 1. 创建数据库mall
    CREATE DATABASE IF NOT EXISTS mall DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    
    -- 2. 使用mall数据库
    USE mall;
    
    -- 3. 创建User表(用户表)
    CREATE TABLE IF NOT EXISTS `User` (
        `id` INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID,主键自增',
        `name` VARCHAR(50) NOT NULL COMMENT '用户名',
        `password` VARCHAR(100) NOT NULL COMMENT '密码',
        `email` VARCHAR(100) DEFAULT NULL COMMENT '邮箱',
        `birthday` DATE DEFAULT NULL COMMENT '生日'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
    
    -- 4. 插入测试数据
    INSERT INTO `User` (name, password, email, birthday)
    VALUES 
    ('张三','123456','zhangsan@qq.com','2000-01-10'),
    ('李四','654321','lisi@163.com','1999-05-20'),
    ('王五','abc123','wangwu@sina.com','2001-08-15');

    注意:

    • Servlet 访问路径错误@WebServlet 注解的路径必须和浏览器访问地址一致,否则会报 404 错误;
    • JSTL 标签不生效:检查 JSP 页面是否引入了 JSTL 标签库,以及项目是否添加了 JSTL 依赖;
    • EL 表达式不生效:检查 JSP 页面是否设置了 isELIgnored="false",部分服务器默认禁用 EL 表达式;
    • 实体类无无参构造方法:JSTL 操作对象时,必须提供无参构造方法,否则会报错;
    • 数据丢失:必须使用 forward 转发,不能用 sendRedirect 重定向,重定向会丢失 request 域数据。

    5、结果

    访问 http://localhost:8080/项目名/persons 后,页面会输出如下人员列表:

    学号:1 姓名:张三 年龄:18 身高:160.0 联系方式:1111111111111
    学号:2 姓名:李四 年龄:20 身高:150.0 联系方式:2222222222222
    学号:3 姓名:王五 年龄:17 身高:155.0 联系方式:3333333333333
    学号:4 姓名:刘六 年龄:19 身高:156.0 联系方式:4444444444444
    学号:5 姓名:赵二 年龄:21 身高:165.0 联系方式:5555555555555

    二、pom.xml 依赖 + DBUtils + User 实体 + UserDao 完整封装

    1、新建部署一个新的模块(可以看我的第一个博客,这里就不讲解了)

    2、Maven pom.xml 核心依赖

    所有 JavaWeb 项目通用,包含 Servlet、JSTL、MySQL、Lombok、Junit

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.example</groupId>
        <artifactId>javaweb-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <!-- 依赖列表 -->
        <dependencies>
            <!-- Junit 单元测试 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.2</version>
                <scope>test</scope>
            </dependency>
    
            <!-- Servlet 核心依赖 -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>4.0.1</version>
                <scope>provided</scope>
            </dependency>
    
            <!-- JSTL 标签库 -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>
    
            <!-- MySQL 驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.49</version>
            </dependency>
    
            <!-- Lombok 简化实体类 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.30</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </project>

    3、DBUtils.java 数据库连接工具类

    负责加载驱动、获取连接、关闭资源,所有 Dao 层共用

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    public class DBUtils {
        // MySQL 5.x 连接信息
        private static final String DRIVER = "com.mysql.jdbc.Driver";
        private static final String URL = "jdbc:mysql://localhost:3306/mall?useSSL=false&characterEncoding=utf-8";
        private static final String USER = "root";
        private static final String PASSWORD = "root";
    
        // 1. 加载驱动(只加载一次)
        static {
            try {
                Class.forName(DRIVER);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        // 2. 获取连接
        public static Connection getConnection() {
            try {
                return DriverManager.getConnection(URL, USER, PASSWORD);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        // 3. 关闭资源
        public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
            try {
                if (rs != null) rs.close();
                if (pstmt != null) pstmt.close();
                if (conn != null) conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void close(Connection conn, PreparedStatement pstmt) {
            close(conn, pstmt, null);
        }
    }

    4、User.java 实体类

    对应数据库 user 表,用来封装用户数据

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
        private int id;
        private String name;
        private String password;
        private String email;
        private String birthday;
    }

    @Data 自动生成

    • getter / setter
    • toString()
    • 无参 / 全参构造

    5、UserDao.java 数据访问层(增删改查完整版)

    负责和数据库交互,实现用户的查询、添加、删除、修改

    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    public class UserDao {
        public List<User> getAll() {
            Connection con = null;
            Statement stmt = null;
            String sql = "select * from User";
            ResultSet rs = null;
            ArrayList<User> users = new ArrayList<>();
            try {
                // 1. 建立数据库连接
                con = DBUtils.getConnection();
                // 2. 获取Statement对象
                stmt = con.createStatement();
                // 3. 执行SQL查询
                rs = stmt.executeQuery(sql);
                // 4. 遍历结果集,封装为User对象
                while (rs.next()) {
                    User user = new User();
                    user.setId(rs.getInt("id"));
                    user.setName(rs.getString("name"));
                    user.setBirthday(rs.getString("birthday"));
                    user.setEmail(rs.getString("email"));
                    user.setPassword(rs.getString("password"));
                    users.add(user);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 5. 关闭资源(按ResultSet → Statement → Connection的顺序)
                DBUtils.close(con, stmt, rs);
            }
            return users;
        }
    }

    (1)添加用户

    在User表中插入一条数据(User对象),返回的值为受影响的行数。

        public int add(User user) {
            int num = 0;
            Connection conn = DBUtils.getConnection();
            try {
                String sql = "insert into User(name,password,email, birthday) values(?,?,?,?)";
                PreparedStatement pst = conn.prepareStatement(sql);
                //把user.getName(),放到了sal语句中的第一个占位符?
               pst.setString(1, user.getName());
                pst.setString(2, user.getPassword());
                pst.setString(3, user.getEmail());
                pst.setString(4, user.getBirthday());
                num = pst.executeUpdate();
                DBUtils.close(null, pst, conn);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return num;
             }

    (2)删除用户

    删除: delete from user where id=1;
    public int deleteUser(int id){
            int num=0;
            Connection con=DBUtils.getConnection();
            try{
                String sql="delete from user where id=?";
                PreparedStatement pst=con.prepareStatement(sql);
                pst.setInt(1,id);
                
                num=pst.executeUpdate();
                DBUtils.close(con, pst, null);
            }catch (Exception e){
                e.printStackTrace();
            }
            return num;
        }
    

    (3)修改用户密码

    public int updateUser(int id,String password) {
            int num = 0;
            Connection con = DBUtils.getConnection();
            try {
                String sql = "update User set password =? where id=?";
                PreparedStatement pst = con.prepareStatement(sql);
                
                pst.setString(1,password);
                pst.setInt(2,id);
                
                num = pst.executeUpdate();
                DBUtils.close(con, pst, null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return num;
        }

    6、配套数据库 SQL(直接运行)

    CREATE DATABASE IF NOT EXISTS mall;
    USE mall;
    
    CREATE TABLE IF NOT EXISTS user (
        id INT PRIMARY KEY AUTO_INCREMENT,
        name VARCHAR(20),
        password VARCHAR(20),
        email VARCHAR(50),
        birthday VARCHAR(50)
    );
    
    INSERT INTO user VALUES
    (1,'张三','123','zs@qq.com','2000-01-01'),
    (2,'李四','456','ls@qq.com','2001-02-02');

    7、Servlet 层(4 个)

    (1)UserServlet 代码(控制层)

    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 java.io.IOException;
    import java.util.List;
    
    @WebServlet("/userList")
    public class UserServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 1. 创建Dao对象
            UserDao userDao = new UserDao();
            
            // 2. 获取所有用户数据
            List<User> userList = userDao.getAll();
            
            // 3. 存入request域
            request.setAttribute("userList", userList);
            
            // 4. 转发到JSP页面展示
            request.getRequestDispatcher("/userList.jsp").forward(request, response);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    (2)AddUserServlet.java(添加)

    @WebServlet("/addUser")
    public class AddUserServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            User user = new User();
            user.setName(request.getParameter("name"));
            user.setPassword(request.getParameter("password"));
            user.setEmail(request.getParameter("email"));
            user.setBirthday(request.getParameter("birthday"));
    
            UserDao dao = new UserDao();
            dao.add(user);
            response.sendRedirect("/userList");
        }
    }

    (3)UpdateUserServlet.java(修改)

    @WebServlet("/updateUser")
    public class UpdateUserServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            int id = Integer.parseInt(request.getParameter("id"));
            String password = request.getParameter("password");
            UserDao dao = new UserDao();
            dao.updateUser(id,password);
            response.sendRedirect("/userList");
        }
    }

    (4)DeleteUserServlet.java(删除)

    @WebServlet("/updateUser")
    public class UpdateUserServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            int id = Integer.parseInt(request.getParameter("id"));
            String password = request.getParameter("password");
            UserDao dao = new UserDao();
            dao.updateUser(id,password);
            response.sendRedirect("/userList");
        }
    }

    8、jsp页面

    (1)userList.jsp 页面(展示层)

    <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>用户列表</title>
        <style>
            table{
                border-collapse: collapse;
                width: 80%;
                margin: 20px auto;
            }
            table,th,td{
                border: 1px solid #333;
                text-align: center;
                padding: 8px;
            }
            th{
                background-color: #f2f2f2;
            }
        </style>
    </head>
    <body>
        <h2 style="text-align: center">用户信息列表</h2>
    
        <table>
            <tr>
                <th>ID</th>
                <th>姓名</th>
                <th>密码</th>
                <th>邮箱</th>
                <th>生日</th>
            </tr>
    
            <%-- JSTL遍历集合 --%>
            <c:forEach items="${userList}" var="user">
                <tr>
                    <td>${user.id}</td>
                    <td>${user.name}</td>
                    <td>${user.password}</td>
                    <td>${user.email}</td>
                    <td>${user.birthday}</td>
                </tr>
            </c:forEach>
        </table>
    </body>
    </html>

    (2)addUser.jsp(添加用户表单)

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>添加用户</title>
        <style>
            form {
                width: 400px;
                margin: 30px auto;
                padding: 20px;
                border: 1px solid #ccc;
                border-radius: 8px;
            }
            input {
                width: 100%;
                padding: 6px;
                margin: 6px 0;
            }
            button {
                width: 100%;
                padding: 8px;
                background: #4CAF50;
                color: white;
                border: none;
                border-radius: 4px;
            }
            h2 {
                text-align: center;
            }
        </style>
    </head>
    <body>
        <h2>添加新用户</h2>
        <form action="addUser" method="post">
            姓名:<input type="text" name="name" required><br>
            密码:<input type="text" name="password" required><br>
            邮箱:<input type="email" name="email" required><br>
            生日:<input type="text" name="birthday" placeholder="例如:2000-01-01" required><br>
            <button type="submit">提交添加</button>
        </form>
    </body>
    </html>

    (3) updateUser.jsp(修改密码页面)

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>修改密码</title>
        <style>
            form {
                width: 400px;
                margin: 50px auto;
                padding: 20px;
                border: 1px solid #ccc;
                border-radius: 8px;
            }
            input {
                width: 100%;
                padding: 6px;
                margin: 10px 0;
            }
            button {
                width: 100%;
                padding: 8px;
                background: #0066cc;
                color: white;
                border: none;
                border-radius: 4px;
            }
            h2 {
                text-align: center;
            }
        </style>
    </head>
    <body>
        <h2>修改用户密码</h2>
        <form action="updateUser" method="post">
            <!-- 隐藏域传递用户ID -->
            <input type="hidden" name="id" value="<%=request.getParameter("id")%>">
    
            新密码:<input type="text" name="password" placeholder="请输入新密码" required><br>
            <button type="submit">确认修改</button>
        </form>
    </body>
    </html>

    9、增删改功能

    (1)测试添加用户功能(AddTest.java)

            功能:向数据库插入一条新的用户记录。

    import org.junit.Test;
    
    public class AddTest {
        @Test
        public void test(){
            // 1. 创建User对象,封装数据
            User user=new User();
            user.setName("李明");
            user.setEmail("liming@163.com");
            user.setPassword("123456");
            user.setBirthday("2003-04-20");
    
            // 2. 创建Dao对象,调用add方法
            UserDao userDao=new UserDao();
            int num=userDao.add(user);
            
            // 3. 判断结果
            if (num>0){
                System.out.println("插入数据成功了!");
            }
        }
    }

    (2)、测试修改密码功能(updateTest.java)

    功能:根据用户 ID 修改密码。

    import org.junit.Test;
    
    public class updateTest {
        @Test
        public void test(){
            // 1. 创建Dao对象
            UserDao userDao=new UserDao();
            
            // 2. 调用修改方法:将ID=1的用户密码改为 0000
            int num=userDao.updateUser(1,"0000");
            
            // 3. 判断结果
            if(num>0){
                System.out.println("密码修改成功");
            }
        }
    }

    (3)、测试删除用户功能(DeleteTest.java)

    功能:根据用户 ID 删除数据。

    import org.junit.Test;
    
    public class DeleteTest {
        @Test
        public void test(){
            // 1. 创建Dao对象
            UserDao userDao= new UserDao();
            
            // 2. 调用删除方法:删除 ID=4 的用户
            int num=userDao.deleteUser(4);
            
            // 3. 判断结果
            if (num>0){
                System.out.println("删除成功!");
            }
        }
    }

    运行结果说明

    • 插入成功:控制台打印 插入数据成功了!
    • 修改成功:控制台打印 密码修改成功
    • 删除成功:控制台打印 删除成功!

    10、完整项目结构(标准 MVC 结构)

    src/
    ├── com/
    │   └── example/
    │       ├── dao/             // 数据访问层
    │       │   └── UserDao.java
    │       ├── entity/          // 实体类
    │       │   └── User.java
    │       ├── servlet/         // 控制层
    │       │   ├── UserServlet.java
    │       │   ├── AddUserServlet.java
    │       │   ├── UpdateUserServlet.java
    │       │   └── DeleteUserServlet.java
    │       ├── utils/           // 工具类
    │       │   └── DBUtils.java
    │       └── test/            // 单元测试
    │           ├── AddTest.java
    │           ├── UpdateTest.java
    │           └── DeleteTest.java
    └── webapp/
        ├── userList.jsp         // 用户列表页面
        ├── addUser.jsp          // 添加用户页面
        └── updateUser.jsp       // 修改密码页面

    11、运行访问方式

    启动服务器后访问:

    http://localhost:8080/你的项目名/userList

    12、核心流程

    • 浏览器访问 UserServlet
    • Servlet 调用 UserDao 获取数据库用户列表
    • 数据存入 request 域
    • 转发到 JSP
    • JSP 使用 JSTL + EL 表达式遍历展示

    三、总结

    1. pom.xml:统一管理 Servlet、JSTL、MySQL、Lombok 依赖;
    2. DBUtils:加载驱动、获取连接、统一关闭资源,Dao 层通用;
    3. User:实体类,封装数据表字段;
    4. UserDao:数据访问层,实现增删改查,与数据库交互。
    5. userList.jsp:展示所有用户,支持删除、修改密码、跳转到添加
    6. addUser.jsp:用户添加表单,提交到 AddUserServlet
    7. updateUser.jsp:根据用户 ID 修改密码,提交到 UpdateUserServlet

      更多推荐