Java Web绩效考评系统实战:Servlet+JSP+DAO部署与二次开发解析

发布时间:2026/10/5 11:16:25
Java Web绩效考评系统实战:Servlet+JSP+DAO部署与二次开发解析 简介Java Web绩效考评系统是一套用于员工绩效考核流程数字化的完整企业级Web应用源码包面向正在学习Java Web开发的学生、需要搭建绩效管理系统的开发者以及HR信息化相关课程实践人员。资源共含509个文件压缩包约982KB文件类型以91个Java源文件、91个编译后的class、39个JSP页面、8个JavaScript脚本、6个CSS样式和1个SQL数据库脚本为主辅以MyEclipse工程配置与SVN元数据可直接导入IDE作为课程设计或毕业设计参考。已有175人学习浏览该资源。系统功能覆盖员工管理、绩效指标设置、周期设定、评价录入、自动计算、报表生成与反馈机制后端体现Spring/Servlet分层与Hibernate/MyBatis等ORM设计思路数据库脚本包含员工表、部门表、绩效标准表等核心表结构。从登录、权限控制到评分流程均有实现代码适合对照描述逆向理解一个完整绩效系统的开发脉络与关键代码组织方式。1. 绩效考评系统 Java Web 版解压就能看的 Servlet JSP DAO 实战项目接到一个 rar 包解压后是 ScoreDAOImpl、UserDAOImpl、LoginServlet、ScoreingServlet 这些类文件这就是一个典型的 Java Web 绩效考评系统。它没有 Spring、没有 MyBatis而是用最原始的 Servlet JSP DAO 把员工管理、绩效指标、评分计算和报表呈现串了起来。对有几年经验的人来说这种老项目一眼能看穿但对刚入门 Java Web 或者准备面试的人来说恰恰是最好的一本教材——你能从 LoginServlet 的一行行代码里理解 HTTP 请求如何落地也能从 ScoreDAOImpl 里看到 JDBC 直连是怎么操作 MySQL 的。这套系统适合三类人想搞懂 Java Web 底层协作的学生、需要二次开发小型绩效系统的外包工程师、以及被 Excel 折腾得想找替代方案的 HR 技术接口人。2. 技术栈拆解从类名看这个 Servlet JSP DAO 老项目的架构2.1 类名里的技术选择没有 Spring反而更适合当教材先别急着部署把 rar 里那些 .class 文件名摊开看一眼就能猜出它的技术栈。UserDAOImpl 说明数据访问层走的是接口实现类的经典封装LoginServlet、ScoreingServlet、ProjectAddServlet、TZUpdateServlet、RPUpdateServlet 这些类名直接落在 Controller 层每一个 Servlet 对应一个业务动作WdatePicker.js.bak 则提示前端用了某款日期选择插件用来在 JSP 页面上弹日历。整体看下来这就是教科书里的三层结构JSP 负责展示Servlet 负责接收请求和转发DAO 实现类负责拼 SQL 操作数据库。没有 Spring 的依赖注入也没有 MyBatis 的 Mapper 代理所有依赖都通过 new 关键字手动 new 出来。这种“原始”结构在今天反而成了优点。Spring Boot 项目一启动就拉起一堆容器哪一步出了问题很难定位而这个项目从头到尾只有 servlet-api 和 mysql-connector-java 两个核心依赖请求从浏览器到 Servlet、再到 DAO、再到数据库每一个环节都可以用 System.out 或 debug 逐步追踪。我建议你在读这个项目时先把这些类名的功能映射出来我列了一个表类名推断的功能对应业务场景UserDAOImpl用户增删改查登录、个人信息维护LoginServlet处理登录请求账号密码校验、Session 管理ScoreingServlet处理评分请求上级对员工的绩效打分ScoreDAOImpl评分数据的读写分数落库、结果查询ProjectAddServlet新增考评项目定义考核维度与周期TZUpdateServlet更新考评周期季度/半年度/年度切换RPUpdateServlet更新考评报告生成或更新绩效报告这个映射并不一定和源码里完全一致但方向不会有偏差。你对这个项目越熟越会发现它就是一个把 Java Web 基础考点——Servlet 生命周期、HttpServletRequest/Response、JDBC 预编译、Session 状态——集中在一个小系统里的实战样本。这些考点恰好也是 Java 基础和 Java 面试题里常被问到的部分后面讲代码时我会以这份映射为准把每个 Servlet 怎么调 DAO、DAO 怎么写 SQL 串成一条完整链路。2.2 从 LoginServlet 到 UserUpdateMyinfoServlet请求在 Servlet 里的流转与跳转一个典型的登录流程是这样用户在 login.jsp 输入 username 和 password表单以 POST 方式提交到 LoginServlet。Servlet 的 doPost 方法先设置 UTF-8 编码再取出两个请求参数调用 UserDAOImpl 的 findByUsernameAndPassword 方法查库。如果返回的 User 不为空就把当前用户放进 Session然后 redirect 到 index.jsp否则在 request 里放一个错误提示forward 回 login.jsp。代码差不多是这样WebServlet(/login) public class LoginServlet extends HttpServlet { private UserDAO userDAO new UserDAOImpl(); Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); String username request.getParameter(username); String password request.getParameter(password); User user userDAO.findByUsernameAndPassword(username, password); if (user ! null) { request.getSession().setAttribute(currentUser, user); response.sendRedirect(request.getContextPath() /index.jsp); } else { request.setAttribute(error, 用户名或密码错误); request.getRequestDispatcher(/login.jsp).forward(request, response); } } }这里有两个细节值得新手注意。第一redirect 和 forward 的区别redirect 是浏览器重新发起一次新请求地址栏会变化forward 是服务端内部跳转地址栏不变但 request 里的属性还能读到。上面的登录失败用 forward因为要带着 error 回页面登录成功用 redirect避免刷新页面时重复提交登录请求。第二我在类上用了 WebServlet(/login) 注解这是 Servlet 3.0 之后的写法如果这个老项目是在 Tomcat 6 或 7 上跑可能会改用 web.xml 里 配置。你解压后可以看下 web.xml 里有没有重复定义如果两边都写了一般以注解为准但某些旧容器不认注解就需要把注解删掉或在 web.xml 里补上。UserUpdateMyinfoServlet 也是同样的套路只是调用的是 UserDAOImpl 里的 updateMyinfo 方法把修改后的姓名、职位、部门等信息更新到数据库。这类 Servlet 的共性很好提取doGet 负责打开页面、doPost 负责提交处理两个方法经常同时存在doGet 拼一个转发跳转doPost 拼一个 update 语句。你把这个模式看懂了整个系统的几十个类就只剩参数差异。2.3 DAO 实现类里的 JDBC 直连为什么连接参数要单独拆出来看完了 Servlet 层再往下就是 DAO 层。UserDAOImpl 和 ScoreDAOImpl 这两兄弟负责所有 SQL 的拼装与执行。早期教学项目里连接数据库的代码经常直接写死在 DAO 里例如public class UserDAOImpl implements UserDAO { private String url jdbc:mysql://localhost:3306/performance_db?useSSLfalsecharacterEncodingutf8; private String username root; private String password 123456; Override public User findByUsernameAndPassword(String name, String pwd) { try { Class.forName(com.mysql.jdbc.Driver); Connection conn DriverManager.getConnection(url, username, password); String sql SELECT * FROM user WHERE username ? AND password ?; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, name); ps.setString(2, pwd); ResultSet rs ps.executeQuery(); if (rs.next()) { User u new User(); u.setId(rs.getInt(id)); u.setUsername(rs.getString(username)); u.setRole(rs.getString(role)); return u; } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } return null; } }这段代码有几个值得细看的点。第一Class.forName(com.mysql.jdbc.Driver) 是注册驱动MySQL 5.x 的驱动类名是 com.mysql.jdbc.DriverMySQL 8.x 则变成了 com.mysql.cj.jdbc.Driver如果项目用的驱动和数据库版本不匹配启动时会直接报 ClassNotFoundException。第二连接字符串里我加了 useSSLfalse 和 characterEncodingutf8useSSL 是为了避免 MySQL 5.7 的 SSL 警告characterEncoding 是解决中文乱码的关键参数这两个参数在后面的避坑部分还要再提。第三SQL 里用 PreparedStatement 而不是 Statement是为了防 SQL 注入参数用 ? 占位然后通过 setString 赋值这个习惯哪怕现在换到 MyBatis 也应该保持。连接参数写死在 DAO 里的最大问题是没法环境切换。开发库、测试库、生产库往往三套账号每次换环境都要改源码重新编译。老项目没有 Spring 管理配置常见做法是把这些参数挪到 src 下的 jdbc.properties 文件里然后写一个 JDBCUtil.java 用静态代码块读属性。如果你拿到的 rar 里已经有这个文件部署时只需要改 properties 里的内容不需要动 Java 代码如果它是写死的我建议你先别急着重构把它跑通后再拆也不迟——第一版的目标是让系统转起来而不是重写架构。3. 功能模块地图从员工管理到绩效评分代码分别落在哪里3.1 登录与个人管理UserDAOImpl 撑起的安全边界绩效考评系统里不可能所有人都是 HR员工、部门主管、HR 管理员的权限差异很大这个系统是怎么处理的呢大概率是在 user 表里放了一个 role 字段登录时带上角色页面菜单根据角色渲染。比如员工登录后只能看自己的分数主管能对下属打评HR 能维护人员和指标。UserDAOImpl 里除了查账号密码还要把 role 查出来封装进 User 对象。权限控制往往不是靠框架而是在每个核心 Servlet 的开头手动检查 Session。很多教学项目都会有下面这段代码HttpSession session request.getSession(false); if (session null || session.getAttribute(currentUser) null) { response.sendRedirect(request.getContextPath() /login.jsp); return; }这种做法的优点是直观缺点是容易漏。假设 ScoreingServlet 里忘了加这段校验那任何人只要知道 URL不登录也能提交评分。所以你在复现时建议逐个 Servlet 检查一遍看是否都有 Session 校验。如果你想更稳妥可以自己写一个简单的 Filter对所有 .jsp 和 .servlet 做拦截放行 /login.jsp 和登录接口其余请求都强制要求 Session 存在。这是老项目升级安全性的第一步。UserUpdateMyinfoServlet 对应的是员工自助修改个人信息。它的实现本质上是先拿 Session 里的 userId把表单里的姓名、手机号、邮箱等字段拼进一条 UPDATE SQL。这里要注意如果这个 Servlet 用的是刚才那种手动校验那么用户只能改自己的信息因为 userId 不是从请求参数里取而是从 Session 里取。如果写代码的人为了省事把 userId 放进了隐藏表单就容易发生越权。看到这里时可以留个心这也是到时候二次开发最该盯的地方。3.2 评分计算链路ScoreingServlet 如何把评价变成可统计的分数评分是绩效系统的核心ScoreingServlet 和 ScoreDAOImpl 承担了主要逻辑。常见的设计是评分页先列出某个员工的绩效指标每个指标带一个权重主管填分数后提交。提交动作会执行两条 SQL第一条插入评分明细第二条读取权重和分数做加权计算。INSERT INTO score (employee_id, indicator_id, scorer_id, score_value, eval_period_id, remark, create_time) VALUES (?, ?, ?, ?, ?, ?, NOW()); SELECT i.weight, s.score_value FROM score s JOIN indicator i ON s.indicator_id i.id WHERE s.employee_id ? AND s.eval_period_id ?;然后 Java 端会做一个循环double totalScore 0; double totalWeight 0; for (ScoreItem item : itemList) { totalScore item.getScoreValue() * item.getWeight(); totalWeight item.getWeight(); } double finalScore totalWeight 0 ? 0 : totalScore / totalWeight;这个逻辑不复杂但容易出错的点在权重归一化。如果指标权重之和不是 100那么最终分会被稀释或放大。老项目一般不会自动检查需要写 SQL 或代码去校验。你可以留意 ScoreingServlet 里是否有对 totalWeight 为 0 的容错如果没有那在评分为 0 的极端情况下一次除零错误就能让页面 500。这也是后续可以加固的地方。评分记录表里还应留一个 eval_period_id 字段用来区分季度、半年度、年度。同一个员工在不同周期会有多份记录ScoreDAOImpl 的查询方法通常会按 employeeId periodId 检索生成该周期的得分列表。如果你在源码里看到类似 findScoreByPeriod 的方法那就是对标这个需求。3.3 考评周期与项目设置TZUpdateServlet、RPUpdateServlet、ProjectAddServlet 各管哪些配置看类名TZUpdateServlet 和 RPUpdateServlet 属于更新类操作ProjectAddServlet 属于新增操作。结合绩效考评的业务场景TZUpdateServlet 很可能是在维护考评周期——把季度、半年度、年度的起止时间做调整。RPUpdateServlet 则可能对应绩效报告的状态更新比如从“草稿”改为“已发布”或者更新报告中的一段总结文字。ProjectAddServlet 则用来新增一个考评项目比如新建一个“2025 年度上半年 KPI 考核”。这类配置页面的套路是有一个 list.jsp 显示现有配置每个配置项旁边有“修改”和“新增”按钮点击后跳到 editProject.jsp 或 editPeriod.jsp表单提交到对应的 Servlet。Servlet 里拿到表单参数调用 DAO 的 insert 或 update 方法最后 redirect 回列表页。这个流程在 JSP 时代非常标准你在复现时只要照着模仿就能加新功能。值得注意的是周期设定和项目设定其实是两个维度。周期是时间上的划分比如 2025 年 Q1项目是考评的具体表头比如“销售额达成率”“客户满意度”。两者会通过 eval_period_id 和 project_id 关联到评分记录。如果你的 rar 包里的表结构比较复杂优先看这两张表的外键关系理解了它们就能理解整个系统的语义。3.4 反推数据库表结构员工表、指标表、评分记录表怎么设计从功能反推数据库至少要有用户表、员工表、部门表、绩效指标表、考评周期表、评分记录表。下面是一个常见的初始化脚本片段CREATE TABLE employee ( id INT PRIMARY KEY AUTO_INCREMENT, emp_no VARCHAR(20) NOT NULL, name VARCHAR(50) NOT NULL, department_id INT, position VARCHAR(50), hire_date DATE ); CREATE TABLE indicator ( id INT PRIMARY KEY AUTO_INCREMENT, project_id INT, name VARCHAR(100) NOT NULL, weight DECIMAL(5,2) NOT NULL DEFAULT 0, sort_order INT DEFAULT 0 ); CREATE TABLE eval_period ( id INT PRIMARY KEY AUTO_INCREMENT, period_name VARCHAR(50) NOT NULL, start_date DATE, end_date DATE, status TINYINT DEFAULT 0 ); CREATE TABLE score ( id INT PRIMARY KEY AUTO_INCREMENT, employee_id INT NOT NULL, indicator_id INT NOT NULL, eval_period_id INT NOT NULL, score_value DECIMAL(5,2) NOT NULL, remark VARCHAR(255), create_time DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_emp_period (employee_id, eval_period_id) );这张表模型没有过度设计但已经能支撑员工管理、指标权重、周期划分、评分记录查询。你拿到源码里的数据库脚本后先跟这个结构对比一下看差别在哪里往往就能知道这个项目是偏教学还是偏生产。生产级项目会在 score 表里加 score_type自评/上级评/同事评、提交状态、审核人等字段而教学项目通常只会留最核心的那几个。4. 在 Tomcat MySQL 上手动跑通从解压到登录的完整部署步骤4.1 环境版本搭配JDK 1.8 Tomcat 8 MySQL 5.7 最顺手老项目最怕版本错配。这个系统既然是用 Servlet JSP DAO 写的我用 JDK 1.8 Tomcat 8.5 MySQL 5.7 这一套跑基本没有版本兼容问题。JDK 8 稳定Tomcat 8 支持 Servlet 3.1MySQL 5.7 的驱动用 5.1.49 就行。如果你本地已经装了 MySQL 8.0也不用降级把数据库驱动换成 8.0.33连接 URL 里把驱动类名和参数改一下即可后面 4.3 会说。这里要特别提醒一下 Tomcat 的版本。Tomcat 9 开始把 Java EE 的包名从 javax 改成了 jakarta而这个老项目的 Servlet 代码全部基于 javax.servlet 写的直接扔到 Tomcat 9 上会报 NoClassDefFoundError: javax/servlet/http/HttpServlet。所以说 Tomcat 8.5 是最省心的选择。如果你只有 Tomcat 9 以上除非把所有 import 都改成 jakarta.servlet否则别折腾。先确认环境java -version mysql --version $CATALINA_HOME/bin/version.sh如果 java -version 显示的是 11 或 17也可以跑但要保证编译时 source/target 设为 1.8否则 Tomcat 8 会拒载。MySQL 的版本主要影响连接 URL 的参数不影响业务代码。这一步只要三项都正常就往下走。4.2 导入数据库脚本建库建表并插入默认账号rar 包里通常会带一个 sql 文件可能是 init.sql 或 performance_db.sql。如果没有就按上一章里的建表脚本自己建。下面以最常见的 init.sql 为例执行命令如下mysql -uroot -p init.sql脚本内容大致是这个意思CREATE DATABASE IF NOT EXISTS performance_db DEFAULT CHARACTER SET utf8mb4; USE performance_db; -- 用户表带角色字段 CREATE TABLE user ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(50) NOT NULL, real_name VARCHAR(50), role VARCHAR(20) DEFAULT EMPLOYEE ); -- 默认管理员账号 INSERT INTO user (username, password, real_name, role) VALUES (admin, 123456, 系统管理员, HR);执行后验证一下USE performance_db; SELECT * FROM user;能看到 admin 这一行就说明库已经起来了。注意如果脚本里没有默认账号你后面登录页面时会卡在登录环节。这种情况不要慌直接手动插一条即可。密码字段在老项目里往往是明文先别指望它加密。另外导入完成后建议用 SHOW TABLES 看一眼表清单像 employee、indicator、score、eval_period 这些核心表都在才说明脚本执行完整SHOW TABLES;4.3 修改数据库连接配置属性文件 vs 写死常量数据库连接配置有两种可能。第一种是项目里有 jdbc.properties 文件位置一般在 src 或 WEB-INF/classes 下。打开后改成你的账号jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/performance_db?useSSLfalsecharacterEncodingutf8 jdbc.usernameroot jdbc.password123456第二种是配置写死在 UserDAOImpl 或 ScoreDAOImpl 里就像 2.3 节那段代码那样。如果是这种你要改的是 Java 源码里的 url、username、password 三个常量改完重新编译。这里有个小建议先全局搜索一下 “jdbc” 或 “DriverManager”把所有出现的地方都改掉不要只看一个类。很多老项目会在每个 DAO 里各写一份连接信息漏改一个就会导致部分功能正常、部分功能报错看起来像玄学实际就是配置没改全。搜索命令可以参考grep -rn DriverManager --include*.java .如果搜出来的结果有多个 Java 文件就要一个一个改。如果配置是共享的那改一个就好。改完后编译时注意带上驱动 jar 的 classpath否则 javac 会报找不到类的错误。这一步做完系统就已经指向你的本地数据库了。4.4 编译与打包用 javac 手动编译或者直接以 exploded 方式部署拿到源码后最直接的方式是导入 IDE。IDEA 或 Eclipse 里打开项目后把它配置成 Web Application 项目然后在 Project Structure 里给 Artifacts 加上 WEB-INF/lib 下的 mysql 驱动再配置一个 Tomcat 运行环境。这样启动时 IDE 会自动编译和部署调试起来比命令行方便很多。如果你不想开 IDE也可以纯命令行编译。假设项目目录结构是 WebContent 下面放 JSP 和 WEB-INFsrc 下面放 Java 源码lib 下有 mysql 驱动。# 在项目根目录下执行 javac -encoding UTF-8 -cp lib/* -d WebContent/WEB-INF/classes src/com/*/*.java这行命令会把所有 Java 文件编译到 WEB-INF/classes 下注意 -encoding UTF-8 是必须的否则带中文注释的源码会编译失败。编译完成后可以打包成 warcd WebContent jar -cvf ../performance.war . cp ../performance.war $TOMCAT_HOME/webapps/然后启动 Tomcatwar 会自动解压。如果你只是本地调试更快的方式是把整个 WebContent 目录直接复制到 webapps/performance/ 下Tomcat 启动时会把目录里的 JSP、class 一起加载省去打包过程。这种方式改 JSP 后不需要重启容器刷新页面就能看到变化推荐调试时用。但要注意改了 Java 类后还是要重新编译并且重启 Tomcat 或重新部署目录光刷新页面不会生效。4.5 启动验证从登录到打分走一遍主流程启动 Tomcat看日志确认没有异常$TOMCAT_HOME/bin/startup.sh tail -f $TOMCAT_HOME/logs/catalina.out看到INFO: Server startup in ... ms后浏览器访问http://localhost:8080/performance/login.jsp输入 admin/123456 登录应该能进入主页面。然后找一个员工打开评分页提交一条评分再回到评分查询页看结果。如果这几个动作都能走通系统就算本地跑起来了。如果卡在某一步先看 catalina.out 里的堆栈也可以看 Tomcat 的 localhost.log。绝大多数问题都出在数据库连接和 Servlet 映射上正好是下一章要避的坑。另外启动前检查一下项目目录里有没有 WEB-INF/web.xml。如果这个文件缺失Tomcat 虽然能加载静态页面但所有 Servlet 的映射都不会生效表现为 JSP 能打开、访问 Servlet 就 404。老项目一般都有但如果 rar 只解压了部分文件容易漏掉。确认一下再启动能省很多时间。5. 避坑手册从启动报错到中文乱码摸过一遍才敢说跑通5.1 数据库连接相关驱动找不到、时区不对、编码不统一先说最常见的驱动问题。现象Tomcat 一启动日志直接报 ClassNotFoundException: com.mysql.jdbc.Driver。原因很直白mysql-connector-java 的 jar 包没有放进 WEB-INF/lib或者你用的是 IntelliJ IDEA虽然给项目加了 library但 Artifacts 里没有带上。解决把所有第三方 jar 拷到 WebContent/WEB-INF/lib 下然后在 IDE 里重新构建 Artifacts。命令行部署的话只要 jar 在 WEB-INF/lib 下Tomcat 会自动加载。另外MySQL 8.x 的驱动类名是 com.mysql.cj.jdbc.Driver和 5.x 的 com.mysql.jdbc.Driver 不一样如果你用的是新驱动记得改 Class.forName 或 URL 里的驱动名。第二类问题集中在连接 URL 上。现象执行查询报 Communications link failure或者插入的中文变成了问号。原因URL 里没有带 serverTimezone 和 characterEncoding 参数MySQL 8 默认时区是 UTC和本地时区有偏差中文乱码则是因为页面、请求、数据库连接三层编码不一致。解决把 URL 改成下面这种写法并保证数据库建库时使用 utf8mb4jdbc:mysql://localhost:3306/performance_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8如果系统已经跑起来改了 URL 后要重启 Tomcat因为连接是启动时建立的。5.2 编译与部署相关class 版本不一致、旧文件缓存现象启动时报 UnsupportedClassVersionError错误信息里会带一段 “compiled by a more recent version of Java”。原因编译时用的 JDK 比运行时的 JDK 版本高。比如你在 JDK 17 环境编译Tomcat 跑在 JDK 8 上JVM 无法加载高版本字节码。解决统一编译和运行环境命令行编译时加-source 1.8 -target 1.8IDEA 里在 Project Structure 的 Modules 中把 Bytecode Version 改到 8。如果还不行就干脆在 JDK 8 的机器上重新编译一遍。另一个现象很迷惑改了 Java 代码重新部署后页面还是旧逻辑。原因通常是 Tomcat 的 work 缓存里保留了旧的 class或者旧 war 解压目录没清干净。解决先停掉 Tomcat删除 webapps/performance 目录和 work/Catalina 目录然后把新的 war 或目录放回去再启动。我一般会写一条清理命令rm -rf $TOMCAT_HOME/webapps/performance $TOMCAT_HOME/work/Catalina部署后真的要验证 class 是否更新可以看 WEB-INF/classes 下的 .class 文件时间戳。5.3 权限校验缺失不登录也能打开评分页现象直接在浏览器地址栏输入 /scoreing 或对应的 Servlet 路径页面能打开甚至能提交评分数据。原因系统只在登录成功后做了跳转核心 Servlet 里缺少 Session 校验。这个项目不是 Spring Security所有访问控制都要靠每个 Servlet 自己写。解决在 ScoreingServlet、ProjectAddServlet 这类写操作的 Servlet 开头都补上检查。如果嫌逐个改太麻烦可以写一个 FilterWebFilter(/*) public class LoginFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) res; String uri request.getRequestURI(); if (uri.endsWith(login.jsp) || uri.endsWith(loginServlet) || uri.contains(/static/)) { chain.doFilter(req, res); } else if (request.getSession(false) ! null request.getSession(false).getAttribute(currentUser) ! null) { chain.doFilter(req, res); } else { response.sendRedirect(request.getContextPath() /login.jsp); } } }这段 Filter 会拦截所有请求白名单放行登录页和静态资源其他请求一律要求 Session 里有 currentUser。加上之后越权访问的现象就不会再出现了。6. 进阶验证跑通之后先做这三步再谈改造系统能登录、能打分、能查报告这只是跑通了。要把它当二次开发的底子我建议先做一遍“三查”查权重、查越权、查连接。具体来说用一个测试员工和测试周期录入一组权重和为 100 的指标打一组分数手工算一遍加权结果再和系统算出来的比对然后换一个普通员工账号尝试直接访问 ScoreingServlet 的 URL确认是否被拦截最后把数据库连接改成连一个故意不存在的库验证系统报错时不会把堆栈打到页面上。这三项过了说明这个老项目至少不会在底层逻辑上翻车。如果一切正常接下来最值得做的一步改造就是换掉裸 JDBC 连接。老项目每个 DAO 都 new Connection高并发一上来连接数就爆。我一般会引入 Druid 连接池改动量不大。先在 lib 里放 druid jar然后写一个连接工具类public class DBUtil { private static DruidDataSource ds new DruidDataSource(); static { ds.setDriverClassName(com.mysql.jdbc.Driver); ds.setUrl(jdbc:mysql://localhost:3306/performance_db?useSSLfalse); ds.setUsername(root); ds.setPassword(123456); ds.setInitialSize(3); ds.setMaxActive(10); } public static Connection getConnection() throws SQLException { return ds.getConnection(); } }然后把 DAO 里的 DriverManager.getConnection 全部替换成 DBUtil.getConnection。替换后重启系统再压一遍评分提交连接数和响应时间都会有明显改善。当然这只是第一步后续还能把明文密码改成 MD5、把 JSP 里的 Java 代码抽到 Servlet 里但那些都是题外话了。从那以后我每次拿到老项目都强迫自己先跑通再重构而且跑通后第一件事永远是做上面那套三查不查完不敢下手。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询