当前位置:首页 > 技术 > 正文内容

JavaWeb学生信息管理平台开发实战:Servlet+JSP+MySQL技术栈

访客 技术 2026年7月13日 5

本文介绍一套基于经典JavaWeb技术栈构建的学生信息管理平台,采用分层架构设计,涵盖用户认证、数据分页、验证码生成等核心功能模块。

技术架构与环境配置

系统采用B/S架构,后端基于Servlet规范处理HTTP请求,JSP负责视图渲染,MySQL作为持久化存储。开发环境要求JDK 8及以上版本,Tomcat 8+作为Web容器,数据库选用MySQL 5.7或更高版本。

核心功能实现

1. 登录认证与验证码机制

登录模块集成图形验证码功能,防止暴力破解。验证码通过内存图像动态生成,采用随机字符组合:

@WebServlet("/captchaServlet")
public class CaptchaServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        // 禁用浏览器缓存
        resp.setHeader("Cache-Control", "no-store");
        resp.setHeader("Pragma", "no-cache");
        resp.setDateHeader("Expires", 0);
        
        int w = 100, h = 40;
        BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = img.createGraphics();
        
        // 绘制背景与干扰线
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, w, h);
        g.setColor(Color.LIGHT_GRAY);
        for(int i=0; i<30; i++) {
            g.drawLine(randomNum(w), randomNum(h), randomNum(w), randomNum(h));
        }
        
        // 生成验证码字符串
        String code = generateCode(4);
        req.getSession().setAttribute("SESS_CAPTCHA", code);
        
        g.setColor(new Color(20, 100, 180));
        g.setFont(new Font("微软雅黑", Font.BOLD, 24));
        g.drawString(code, 20, 28);
        g.dispose();
        
        ImageIO.write(img, "PNG", resp.getOutputStream());
    }
    
    private String generateCode(int len) {
        String chars = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
        Random rnd = new Random();
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<len; i++) {
            sb.append(chars.charAt(rnd.nextInt(chars.length())));
        }
        return sb.toString();
    }
    
    private int randomNum(int bound) {
        return new Random().nextInt(bound);
    }
}

登录验证Servlet处理用户凭据校验,同时验证图形验证码:

@WebServlet("/authServlet")
public class AuthServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        HttpSession sess = req.getSession();
        
        // 验证码校验
        String inputCode = req.getParameter("captcha");
        String sessCode = (String) sess.getAttribute("SESS_CAPTCHA");
        sess.removeAttribute("SESS_CAPTCHA"); // 一次性使用
        
        if(sessCode == null || !sessCode.equalsIgnoreCase(inputCode)) {
            req.setAttribute("errMsg", "验证码错误或已过期");
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
            return;
        }
        
        // 封装登录实体
        Map<String, String[]> params = req.getParameterMap();
        Account account = new Account();
        try {
            BeanUtils.populate(account, params);
        } catch(Exception ex) {
            ex.printStackTrace();
        }
        
        // 业务层验证
        AccountService svc = new AccountServiceImpl();
        Account user = svc.authenticate(account);
        
        if(user != null) {
            sess.setAttribute("currUser", user);
            resp.sendRedirect(req.getContextPath() + "/listServlet");
        } else {
            req.setAttribute("errMsg", "账号或密码不正确");
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }
}

2. 请求拦截与编码过滤

通过Filter实现全站编码统一与登录状态拦截:

public class SecurityFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        
        String path = request.getRequestURI();
        String action = request.getParameter("action");
        
        // 白名单放行
        boolean isPublic = path.endsWith("login.jsp") 
            || path.endsWith("register.jsp")
            || path.contains("authServlet")
            || path.contains("captchaServlet")
            || "register".equals(action)
            || path.matches(".*\\.(css|js|png|jpg)$");
        
        if(isPublic || request.getSession().getAttribute("currUser") != null) {
            chain.doFilter(req, res);
        } else {
            response.sendRedirect("login.jsp");
        }
    }
}

3. 学生信息CRUD操作

新增学生记录

@WebServlet("/createServlet")
public class CreateServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        
        Map<String, String[]> data = req.getParameterMap();
        Student stu = new Student();
        try {
            BeanUtils.populate(stu, data);
        } catch(Exception e) {
            e.printStackTrace();
        }
        
        StudentService svc = new StudentServiceImpl();
        svc.create(stu);
        
        resp.sendRedirect(req.getContextPath() + "/listServlet");
    }
}

分页查询与条件检索

@WebServlet("/listServlet")
public class ListServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        
        String pageNum = req.getParameter("pageNum");
        String pageSize = req.getParameter("pageSize");
        
        int num = (pageNum == null || pageNum.isEmpty()) ? 1 : Integer.parseInt(pageNum);
        int size = (pageSize == null || pageSize.isEmpty()) ? 10 : Integer.parseInt(pageSize);
        
        Map<String, String[]> criteria = req.getParameterMap();
        
        StudentService svc = new StudentServiceImpl();
        PageResult<Student> result = svc.queryByPage(num, size, criteria);
        
        req.setAttribute("pageData", result);
        req.setAttribute("searchParams", criteria);
        req.getRequestDispatcher("/list.jsp").forward(req, resp);
    }
}

修改与删除操作

@WebServlet("/modifyServlet")
public class ModifyServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        
        Map<String, String[]> data = req.getParameterMap();
        Student stu = new Student();
        try {
            BeanUtils.populate(stu, data);
        } catch(Exception e) {
            e.printStackTrace();
        }
        
        StudentService svc = new StudentServiceImpl();
        svc.update(stu);
        
        resp.sendRedirect(req.getContextPath() + "/listServlet");
    }
}

@WebServlet("/removeServlet")
public class RemoveServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        String[] ids = req.getParameterValues("stuId");
        
        StudentService svc = new StudentServiceImpl();
        svc.batchDelete(ids);
        
        resp.sendRedirect(req.getContextPath() + "/listServlet");
    }
}

4. 单条记录查询

@WebServlet("/detailServlet")
public class DetailServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        String sid = req.getParameter("sid");
        
        StudentService svc = new StudentServiceImpl();
        Student stu = svc.findById(sid);
        
        req.setAttribute("student", stu);
        req.getRequestDispatcher("/edit.jsp").forward(req, resp);
    }
}

用户注册功能

@WebServlet("/signupServlet")
public class SignupServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        
        Map<String, String[]> data = req.getParameterMap();
        Account acc = new Account();
        try {
            BeanUtils.populate(acc, data);
        } catch(Exception e) {
            e.printStackTrace();
        }
        
        AccountService svc = new AccountServiceImpl();
        svc.register(acc);
        
        resp.sendRedirect(req.getContextPath() + "/login.jsp");
    }
}

数据库设计要点

系统涉及两张核心数据表:学生信息表(存储学号、姓名、性别、专业、联系方式等字段)与用户表(存储登录账号、加密密码、角色权限等)。建议采用连接池技术管理数据库连接,提升并发性能。

前端交互说明

视图层采用JSP+JSTL技术,通过EL表达式展示后端数据。列表页支持分页导航、条件筛选、批量勾选删除等交互功能。表单提交采用POST方法,配合隐藏域传递记录主键。

标签: Servlet

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。