杰瑞科技汇

Java Web学生管理系统如何实现核心功能?

项目概述

功能需求

一个基础的学生管理系统应具备以下核心功能:

Java Web学生管理系统如何实现核心功能?-图1
(图片来源网络,侵删)
  • 学生信息管理
    • 查看所有学生列表(分页)
    • 添加新学生
    • 根据ID查询学生信息
    • 编辑学生信息
    • 根据ID删除学生
  • 登录功能:管理员登录系统,防止未授权访问。

技术选型

  • 前端:
    • HTML / CSS / JavaScript: 页面结构和样式。
    • JSP (JavaServer Pages): 动态生成页面。
    • JSTL (JSP Standard Tag Library): 简化 JSP 中的 Java 代码。
    • EL (Expression Language): 在 JSP 中获取数据。
  • 后端:
    • Servlet: 处理 HTTP 请求,作为控制器。
    • JDBC: 连接和操作 MySQL 数据库。
    • JavaBean: 封装数据(如 Student 类)。
  • 数据库: MySQL
  • 服务器: Apache Tomcat
  • 构建工具: Maven (用于管理项目依赖)
  • 开发工具: IntelliJ IDEA 或 Eclipse

项目结构 (MVC 架构)

一个典型的 Maven Web 项目结构如下:

student-management-system/
├── src/
│   ├── main/
│   │   ├── java/                 // Java 源代码
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── sms/
│   │   │               ├── controller/  // Servlet 控制器
│   │   │               │   ├── StudentServlet.java
│   │   │               │   └── LoginServlet.java
│   │   │               ├── dao/         // 数据访问层
│   │   │               │   ├── impl/
│   │   │               │   │   └── StudentDaoImpl.java
│   │   │               │   └── StudentDao.java
│   │   │               ├── model/        // 实体/模型层
│   │   │               │   └── Student.java
│   │   │               ├── util/         // 工具类
│   │   │               │   └── DBUtil.java
│   │   │               └── filter/       // 过滤器
│   │   │                   └── LoginFilter.java
│   │   ├── resources/             // 配置文件 (如 db.properties)
│   │   └── webapp/                // Web 应用根目录
│   │       ├── WEB-INF/
│   │       │   ├── lib/           // 第三方 JAR 包 (由 Maven 自动管理)
│   │       │   └── web.xml        // 部署描述符
│   │       ├── css/               // CSS 样式文件
│   │       │   └── style.css
│   │       ├── js/                // JavaScript 文件
│   │       └── jsp/               // JSP 页面
│   │           ├── login.jsp
│   │           ├── student/
│   │           │   ├── list.jsp
│   │           │   ├── add.jsp
│   │           │   └── edit.jsp
│   │           └── index.jsp       // 欢迎页,重定向到登录页
│   └── test/                      // 测试代码
└── pom.xml                        // Maven 项目配置文件

详细实现步骤

步骤 1:环境准备与项目创建

  1. 安装 JDK, Maven, MySQL, Tomcat, IntelliJ IDEA。
  2. 在 IDEA 中创建一个新的 Maven 项目,选择 maven-archetype-webapp 模板。
  3. 配置 pom.xml,添加项目依赖:
    <dependencies>
        <!-- Servlet API -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- JSP API -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
            <scope>provided</scope>
        </dependency>
        <!-- JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- MySQL Driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
    </dependencies>

步骤 2:数据库设计

在 MySQL 中创建数据库和表。

CREATE DATABASE sms_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE sms_db;
-- 管理员表 (用于登录)
CREATE TABLE `admin` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `username` VARCHAR(50) NOT NULL UNIQUE,
  `password` VARCHAR(50) NOT NULL
);
-- 学生表
CREATE TABLE `student` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(50) NOT NULL,
  `gender` VARCHAR(10),
  `age` INT,
  `email` VARCHAR(100),
  `phone` VARCHAR(20)
);
-- 插入一个默认管理员账户
INSERT INTO `admin` (username, password) VALUES ('admin', 'admin123');

步骤 3:创建数据库连接工具类 (DBUtil)

src/main/java/com/example/sms/util 目录下创建 DBUtil.java,用于管理数据库连接。

// DBUtil.java
package com.example.sms.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class DBUtil {
    private static String url;
    private static String user;
    private static String password;
    private static String driver;
    static {
        try {
            // 读取 db.properties 文件
            InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
            Properties props = new Properties();
            props.load(is);
            url = props.getProperty("url");
            user = props.getProperty("user");
            password = props.getProperty("password");
            driver = props.getProperty("driver");
            // 加载驱动
            Class.forName(driver);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }
    public static void closeAll(ResultSet rs, Statement stmt, Connection conn) {
        try {
            if (rs != null) rs.close();
            if (stmt != null) stmt.close();
            if (conn != null) conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

src/main/resources 目录下创建 db.properties 文件:

Java Web学生管理系统如何实现核心功能?-图2
(图片来源网络,侵删)
# db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/sms_db?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
user=root
password=your_mysql_password

步骤 4:创建 Model (JavaBean)

src/main/java/com/example/sms/model 目录下创建 Student.java

// Student.java
package com.example.sms.model;
public class Student {
    private int id;
    private String name;
    private String gender;
    private int age;
    private String email;
    private String phone;
    // Getters and Setters
    // Constructor (no-args and all-args)
    // toString()
    // (省略,标准 JavaBean 代码)
}

步骤 5:创建 DAO (Data Access Object) 层

DAO 层负责与数据库进行交互。

  1. 创建接口 StudentDao.java

    // StudentDao.java
    package com.example.sms.dao;
    import com.example.sms.model.Student;
    import java.util.List;
    public interface StudentDao {
        List<Student> findAll();
        Student findById(int id);
        void add(Student student);
        void update(Student student);
        void deleteById(int id);
    }
  2. 创建实现类 StudentDaoImpl.java

    Java Web学生管理系统如何实现核心功能?-图3
    (图片来源网络,侵删)
    // StudentDaoImpl.java
    package com.example.sms.dao.impl;
    import com.example.sms.dao.StudentDao;
    import com.example.sms.model.Student;
    import com.example.sms.util.DBUtil;
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.List;
    public class StudentDaoImpl implements StudentDao {
        @Override
        public List<Student> findAll() {
            List<Student> students = new ArrayList<>();
            String sql = "SELECT * FROM student";
            Connection conn = null;
            PreparedStatement pstmt = null;
            ResultSet rs = null;
            try {
                conn = DBUtil.getConnection();
                pstmt = conn.prepareStatement(sql);
                rs = pstmt.executeQuery();
                while (rs.next()) {
                    Student student = new Student();
                    student.setId(rs.getInt("id"));
                    student.setName(rs.getString("name"));
                    student.setGender(rs.getString("gender"));
                    student.setAge(rs.getInt("age"));
                    student.setEmail(rs.getString("email"));
                    student.setPhone(rs.getString("phone"));
                    students.add(student);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                DBUtil.closeAll(rs, pstmt, conn);
            }
            return students;
        }
        // ... 实现其他接口方法 (findById, add, update, deleteById)
        // (代码逻辑类似,只是 SQL 语句不同)
    }

步骤 6:创建 Controller (Servlet) 层

Servlet 作为控制器,接收请求,调用 DAO 处理数据,然后转发给 JSP 显示。

  1. 创建 StudentServlet.java

    // StudentServlet.java
    package com.example.sms.controller;
    import com.example.sms.dao.StudentDao;
    import com.example.sms.dao.impl.StudentDaoImpl;
    import com.example.sms.model.Student;
    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("/student/*") // 匹配 /student/ 下的所有请求
    public class StudentServlet extends HttpServlet {
        private StudentDao studentDao = new StudentDaoImpl();
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String pathInfo = req.getPathInfo();
            if (pathInfo == null || pathInfo.equals("/list")) {
                listStudents(req, resp);
            } else if (pathInfo.equals("/add")) {
                req.getRequestDispatcher("/jsp/student/add.jsp").forward(req, resp);
            } else if (pathInfo.equals("/edit")) {
                int id = Integer.parseInt(req.getParameter("id"));
                Student student = studentDao.findById(id);
                req.setAttribute("student", student);
                req.getRequestDispatcher("/jsp/student/edit.jsp").forward(req, resp);
            } else if (pathInfo.equals("/delete")) {
                int id = Integer.parseInt(req.getParameter("id"));
                studentDao.deleteById(id);
                resp.sendRedirect(req.getContextPath() + "/student/list");
            }
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.setCharacterEncoding("UTF-8");
            String pathInfo = req.getPathInfo();
            if (pathInfo.equals("/add")) {
                addStudent(req, resp);
            } else if (pathInfo.equals("/update")) {
                updateStudent(req, resp);
            }
        }
        private void listStudents(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            List<Student> students = studentDao.findAll();
            req.setAttribute("students", students);
            req.getRequestDispatcher("/jsp/student/list.jsp").forward(req, resp);
        }
        private void addStudent(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            Student student = new Student();
            student.setName(req.getParameter("name"));
            student.setGender(req.getParameter("gender"));
            student.setAge(Integer.parseInt(req.getParameter("age")));
            student.setEmail(req.getParameter("email"));
            student.setPhone(req.getParameter("phone"));
            studentDao.add(student);
            resp.sendRedirect(req.getContextPath() + "/student/list");
        }
        private void updateStudent(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            Student student = new Student();
            student.setId(Integer.parseInt(req.getParameter("id")));
            student.setName(req.getParameter("name"));
            student.setGender(req.getParameter("gender"));
            student.setAge(Integer.parseInt(req.getParameter("age")));
            student.setEmail(req.getParameter("email"));
            student.setPhone(req.getParameter("phone"));
            studentDao.update(student);
            resp.sendRedirect(req.getContextPath() + "/student/list");
        }
    }
  2. 创建 LoginServlet.java

    // LoginServlet.java
    package com.example.sms.controller;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    javax.servlet.http.HttpSession;
    import java.io.IOException;
    @WebServlet("/login")
    public class LoginServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.getRequestDispatcher("/jsp/login.jsp").forward(req, resp);
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            // 这里应该查询数据库验证,我们为了简化,直接写死
            if ("admin".equals(username) && "admin123".equals(password)) {
                HttpSession session = req.getSession();
                session.setAttribute("admin", username);
                resp.sendRedirect(req.getContextPath() + "/student/list");
            } else {
                resp.sendRedirect(req.getContextPath() + "/login?error=1");
            }
        }
    }

步骤 7:创建 Filter (登录验证)

创建一个过滤器,检查用户是否已登录,如果未登录则重定向到登录页。

  1. 创建 LoginFilter.java

    // LoginFilter.java
    package com.example.sms.filter;
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    javax.servlet.http.HttpSession;
    import java.io.IOException;
    @WebFilter("/*") // 过滤所有请求
    public class LoginFilter implements Filter {
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
            String path = request.getRequestURI().substring(request.getContextPath().length());
            // 如果是登录相关或静态资源,直接放行
            if (path.startsWith("/login") || path.startsWith("/jsp/") || path.endsWith(".css") || path.endsWith(".js")) {
                chain.doFilter(req, resp);
                return;
            }
            HttpSession session = request.getSession(false);
            if (session == null || session.getAttribute("admin") == null) {
                response.sendRedirect(request.getContextPath() + "/login");
            } else {
                chain.doFilter(req, resp);
            }
        }
    }

步骤 8:创建 View (JSP) 页面

webapp/jsp 目录下创建 JSP 文件。

  1. login.jsp

    <%-- login.jsp --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录</title>
    </head>
    <body>
    <h2>学生管理系统 - 登录</h2>
    <%-- 显示错误信息 --%>
    <% if(request.getParameter("error") != null) { %>
        <p style="color: red;">用户名或密码错误!</p>
    <% } %>
    <form action="${pageContext.request.contextPath}/login" method="post">
        用户名: <input type="text" name="username"><br>
        密码:   <input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
    </body>
    </html>
  2. list.jsp (学生列表页)

    <%-- list.jsp --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>学生列表</title>
        <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
    </head>
    <body>
    <h2>学生信息列表</h2>
    <a href="${pageContext.request.contextPath}/student/add">添加新学生</a>
    <table border="1">
        <tr>
            <th>ID</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
            <th>邮箱</th>
            <th>电话</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${students}" var="student">
            <tr>
                <td>${student.id}</td>
                <td>${student.name}</td>
                <td>${student.gender}</td>
                <td>${student.age}</td>
                <td>${student.email}</td>
                <td>${student.phone}</td>
                <td>
                    <a href="${pageContext.request.contextPath}/student/edit?id=${student.id}">编辑</a>
                    <a href="${pageContext.request.contextPath}/student/delete?id=${student.id}" onclick="return confirm('确定删除吗?')">删除</a>
                </td>
            </tr>
        </c:forEach>
    </table>
    </body>
    </html>
  3. add.jspedit.jsp 这两个页面类似,add.jsp 是空表单,edit.jsp 会从 request 中获取 Student 对象并填充表单,这里省略具体代码,逻辑与 list.jsp 中的链接和表单提交对应。

步骤 9:配置 web.xml

虽然我们使用了 @WebServlet@WebFilter 注解,但为了确保完整性和兼容性,最好在 webapp/WEB-INF/web.xml 中进行基本配置。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <display-name>Student Management System</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

webapp/index.jsp 中,添加重定向到登录页的代码:

<%-- index.jsp --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:forward page="/login"/>

步骤 10:添加 CSS 样式

webapp/css/style.css 中添加一些基本样式,让页面看起来更美观。

/* style.css */
body {
    font-family: Arial, sans-serif;
    margin: 20px;
}
table {
    width: 100%;
    border-collapse: collapse;
}
th, td {
    border: 1px solid #ddd;
    padding: 8px;
    text-align: left;
}
th {
    background-color: #f2f2f2;
}
a {
    margin-right: 10px;
    text-decoration: none;
}
a:hover {
    text-decoration: underline;
}

运行与测试

  1. 配置 Tomcat:在 IDEA 中配置好 Tomcat 服务器。
  2. 部署项目:将项目部署到 Tomcat。
  3. 启动服务器:运行 Tomcat。
  4. 访问:在浏览器中输入 http://localhost:8080/your_project_name/
    • 系统会自动跳转到登录页面。
    • 输入用户名 admin,密码 admin123 登录。
    • 登录成功后,进入学生列表页面,可以添加、编辑、删除学生信息。

进阶与优化方向

这个基础版本已经实现了核心功能,但还可以从以下几个方面进行优化和扩展:

  1. 分页功能:当学生数据很多时,列表页需要分页显示,可以在 StudentDao 中添加 findByPage(int page, int size) 方法,并在 StudentServletlist.jsp 中实现分页逻辑。
  2. 查询功能:添加按姓名、学号等条件查询学生的功能。
  3. 前端框架:使用 Bootstrap 或 Vue.js/React 等现代前端框架来优化 UI 交互体验。
  4. 框架整合
    • Spring MVC:用 Spring 框架替代原生 Servlet,实现更强大的依赖注入和面向切面编程。
    • MyBatis / JPA:用 MyBatis 或 JPA (Hibernate) 框架替代原生 JDBC,简化数据库操作。
  5. 安全性增强
    • 对密码进行加密存储(如 MD5, BCrypt)。
    • 使用 PreparedStatement 防止 SQL 注入(当前代码已做到)。
    • 实现更细粒度的权限控制。
  6. 异常处理:使用全局异常处理器 (HandlerExceptionResolver in Spring) 来统一处理程序中的异常,避免直接在 Servlet 中 try-catch。
  7. 日志框架:集成 Log4j 或 SLF4J 来记录系统运行日志,方便排查问题。

这个项目是学习 Java Web 开发的绝佳实践,通过亲手实现,你可以深刻理解 HTTP 请求/响应、MVC 设计模式、数据库交互等核心概念。

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