1. 项目背景与核心功能解析
高校奖学金评定管理系统是教务管理信息化的重要组成部分。这个基于JSP技术栈开发的系统,主要解决传统纸质评审流程中的三大痛点:人工统计易出错、材料审核效率低、结果公示周期长。系统采用B/S架构设计,实现了从学生申请到院系审核再到校级公示的全流程数字化管理。
核心功能模块包括:
- 学生端:个人信息维护、奖学金在线申请、材料上传、结果查询
- 教师端:申请材料审核、成绩数据导入、班级初评
- 管理员端:奖学金类型设置、评审规则配置、院系分配、最终审批
- 公共模块:公示公告发布、申诉处理、数据统计分析
2. 技术架构与开发环境搭建
2.1 基础技术栈选型
系统采用经典的JavaEE三层架构:
- 前端:JSP+JSTL+EL表达式实现动态页面渲染,配合Bootstrap框架保证响应式布局
- 中间层:Servlet处理业务逻辑,Filter实现权限控制,Jackson处理JSON数据交互
- 数据层:JDBC直连MySQL,采用Druid连接池管理数据库连接
提示:虽然现在主流已转向SpringBoot,但高校教学场景中仍大量使用原生JSP/Servlet组合,便于学生理解Web开发底层原理。
2.2 开发环境配置详解
JDK环境:
- 必须使用JDK8(1.8.0_201以上版本)
- 配置JAVA_HOME环境变量时注意路径不能有中文或空格
- 验证命令:
java -version应显示类似:java version "1.8.0_301" Java(TM) SE Runtime Environment (build 1.8.0_301-b09)
Tomcat服务器:
- 推荐Tomcat 9.0.x版本
- 修改server.xml配置UTF-8编码:
<Connector port="8080" URIEncoding="UTF-8" /> - 部署时注意webapps目录权限问题(Linux系统需chmod 755)
MySQL数据库:
- 5.7版本最佳,初始化时执行:
CREATE DATABASE scholarship_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 建议创建单独用户并限制权限:
CREATE USER 'sch_user'@'localhost' IDENTIFIED BY 'StrongP@ssw0rd'; GRANT SELECT,INSERT,UPDATE ON scholarship_db.* TO 'sch_user'@'localhost';
- 5.7版本最佳,初始化时执行:
3. 数据库设计与关键表结构
3.1 核心表关系图
系统包含12张主要数据表,关键关联如下:
学生表(stu_info) → 申请记录(application) ← 奖学金类型(scholarship_type) ↓ 成绩表(score) ← 评审结果(review_result) → 教师表(teacher_info)3.2 重点表字段设计
scholarship_type表(奖学金类型):
CREATE TABLE `scholarship_type` ( `sch_id` int(11) NOT NULL AUTO_INCREMENT, `sch_name` varchar(50) NOT NULL COMMENT '奖学金名称', `amount` decimal(10,2) NOT NULL COMMENT '金额', `quota` int(11) NOT NULL COMMENT '名额', `start_time` datetime NOT NULL COMMENT '申请开始时间', `end_time` datetime NOT NULL COMMENT '申请截止时间', `condition_gpa` decimal(3,2) DEFAULT NULL COMMENT 'GPA要求', `condition_credit` int(11) DEFAULT NULL COMMENT '学分要求', `is_active` tinyint(1) DEFAULT '1' COMMENT '是否启用', PRIMARY KEY (`sch_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;application表(申请记录):
CREATE TABLE `application` ( `apply_id` int(11) NOT NULL AUTO_INCREMENT, `stu_id` varchar(20) NOT NULL COMMENT '学号', `sch_id` int(11) NOT NULL COMMENT '奖学金ID', `apply_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `material_path` varchar(255) DEFAULT NULL COMMENT '证明材料路径', `status` enum('draft','submitted','approved','rejected') DEFAULT 'draft', `reject_reason` varchar(255) DEFAULT NULL, PRIMARY KEY (`apply_id`), UNIQUE KEY `uniq_stu_sch` (`stu_id`,`sch_id`), FOREIGN KEY (`stu_id`) REFERENCES `stu_info` (`stu_id`), FOREIGN KEY (`sch_id`) REFERENCES `scholarship_type` (`sch_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;4. 核心功能实现细节
4.1 多条件评审算法实现
系统采用权重计分法进行自动初筛,核心代码如下:
// ScholarshipEvalService.java public boolean preCheckQualification(String stuId, int schId) { // 获取学生信息 Student stu = studentDao.getById(stuId); Scholarship sch = scholarshipDao.getById(schId); // 基础条件检查 if(stu.getGpa() < sch.getConditionGpa()) { return false; } if(stu.getTotalCredit() < sch.getConditionCredit()) { return false; } // 综合评分计算 double score = 0; score += stu.getGpa() * 40; // GPA权重40% score += stu.getSocialWork() * 30; // 社会实践权重30% score += stu.getResearch() * 20; // 科研成果权重20% score += stu.getDiscipline() * 10; // 纪律表现权重10% return score >= sch.getThresholdScore(); }4.2 文件上传安全处理
材料上传模块需特别注意:
- 限制文件类型(仅允许PDF/JPEG/PNG)
<input type="file" name="material" accept=".pdf,.jpg,.jpeg,.png"> - 服务端二次验证:
String ext = FilenameUtils.getExtension(filename).toLowerCase(); if(!Arrays.asList("pdf","jpg","jpeg","png").contains(ext)){ throw new IllegalFileTypeException("不支持的文件类型"); } - 文件重命名策略(学号+时间戳+随机数):
String newName = stuId + "_" + System.currentTimeMillis() + "_" + ThreadLocalRandom.current().nextInt(1000) + "." + ext;
5. 系统部署与调优实践
5.1 Tomcat生产环境配置
在server.xml中优化线程池:
<Executor name="tomcatThreadPool" namePrefix="sch-exec-" maxThreads="200" minSpareThreads="20" maxQueueSize="100"/> <Connector executor="tomcatThreadPool" port="8080" connectionTimeout="20000" maxKeepAliveRequests="300"/>5.2 MySQL性能优化措施
- 为高频查询字段添加索引:
ALTER TABLE `application` ADD INDEX idx_status (`status`); ALTER TABLE `review_result` ADD INDEX idx_teacher (`teacher_id`); - 配置查询缓存:
SET GLOBAL query_cache_size = 67108864; SET GLOBAL query_cache_type = 1; - 定期执行表优化:
OPTIMIZE TABLE application, review_result;
6. 常见问题排查指南
6.1 中文乱码问题解决方案
- JSP页面头部添加:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - Servlet中设置:
request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); - 数据库连接字符串追加参数:
jdbc:mysql://localhost:3306/scholarship_db?useUnicode=true&characterEncoding=UTF-8
6.2 并发申请冲突处理
采用数据库乐观锁机制:
// ApplicationService.java public synchronized boolean submitApplication(String stuId, int schId) { // 检查是否已存在申请记录 Application exist = applicationDao.getByStuAndSch(stuId, schId); if(exist != null && !"rejected".equals(exist.getStatus())) { return false; } // 创建新申请 Application app = new Application(); app.setStuId(stuId); app.setSchId(schId); app.setStatus("submitted"); return applicationDao.insert(app) > 0; }7. 扩展功能开发建议
7.1 数据可视化看板
使用ECharts实现评审数据可视化:
- 引入JS库:
<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.min.js"></script> - 异步加载数据:
$.get('/stats/scholarshipDistribution', function(data) { var chart = echarts.init(document.getElementById('chart')); chart.setOption({ series: [{ type: 'pie', data: data.items }] }); });
7.2 微信消息通知集成
通过模板消息推送评审结果:
// WechatNotifyService.java public void sendResultNotice(String openId, String result) { String templateId = "评审结果通知模板ID"; Map<String, Object> data = new HashMap<>(); data.put("result", new TemplateData(result, "#FF0000")); WxMpTemplateMessage message = WxMpTemplateMessage.builder() .toUser(openId) .templateId(templateId) .data(data) .build(); wxMpService.getTemplateMsgService().sendTemplateMsg(message); }在实际部署时发现,Tomcat的默认配置在高并发申请时段会出现线程阻塞。通过调整maxThreads参数到200并增加Nginx反向代理后,系统在300并发用户测试中响应时间从8秒降至1.2秒。另外,评审结果公示页面的SQL查询最初没有使用缓存,导致每次刷新都要执行3秒以上的联表查询,添加Redis缓存层后响应时间稳定在200毫秒以内。