多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

JSP+Tomcat毕设实战:人才招聘系统设计与代码还原

JSP+Tomcat毕设实战:人才招聘系统设计与代码还原 简介一份基于Java Web的人才招聘系统设计与实现文档面向Java方向毕业设计、课程设计以及需要了解网络招聘系统设计流程的开发者。文档以人才招聘管理信息系统为背景系统划分主页面、企业招聘、个人求职、管理员四大部分详细说明个人注册与求职信息发布、企业注册与招聘信息维护、简历浏览与邮件通信以及管理员对求职者、公司、招聘广告的审核管理。整体采用JSPTomcatSQL ServerJDBC技术栈覆盖开发背景、技术选型、系统模块图、数据库表结构和页面设计等内容。资源包仅含1个doc文件大小1.07MB为可编辑Word文档方便对照摘要、目录和模块设计进行二次修改。该文档已有484人学习下载对完成Java Web毕业设计或搭建小型招聘系统有直接的参考价值。1. 拿到手的是一份论文文档JSPTomcat 毕设的骨架和六张表都在里面临近答辩才拿到题目、想抄近路又怕翻车的人对「基于 Java Web 的人才招聘系统设计与实现」这一类毕业设计文档应该不陌生。这份 .doc 不是现成源码包而是一份完整论文文档从开发背景、技术选型到数据库六张表、首页设计、登录页面设计全都有甚至给出了数据库连接类 Conn 的代码开头。换句话说它能帮你省掉搭论文骨架和理清模块关系的几天时间但代码要自己按文档补全。适合两类人一是 Java Web 毕设选了类似题目的在校生二是想快速理解 JSPServlet 老项目结构、准备面试项目复盘的在职者。我先说结论这份资源的价值在于「结构和字段设计可以直接抄」坑也集中在「环境兼容和数据表还原」上下面按章节拆开讲。2. 技术选型与模块框架从 JSP 与 ASP 之争到三个登录入口的功能闭环2.1 为什么当年选 JSP 而不是 ASP执行机制的分水岭文档第二章花了大量篇幅对比 JSP 与 ASP这个对比到今天依然能解释很多老项目的行为。ASP 是 Windows IIS 自带脚本语言语法接近 VB上手快但本质是解释执行——每次请求都要重新解释脚本。JSP 则不同它第一次被请求时会被编译成 Servlet 字节码之后驻留在服务器内存中直接执行。正因为存在「第一次编译」这个动作JSP 首次访问会明显偏慢后续响应速度反超 ASP这是 JSP 页面响应速度的核心机制。选 JSP 还有两个决定性理由。其一跨平台。JSP 基于 Java一处编写到处运行应用可以部署在 Windows 也能跑在 Linux这点对于毕设答辩时换环境演示很重要其二JDBC 统一数据库访问。文档里明确提到 JDBC 是 Java 访问数据库的标准接口换数据库不用改业务代码只改连接串。这套组合到今天依然是 Java Web 老项目的主流基因理解了这些选型理由后面改代码才知道哪里能动、哪里不能动。2.2 三个角色三条线个人、企业、管理员的完整功能闭环文档第三章把系统拆成四部分本质是三个角色加一个公共首页。首页承担入口职责个人求职登录、企业招聘登录、管理员登录外加两类注册。个人这条线是「注册→登录→发布求职信息→删除求职信息→修改个人信息→浏览招聘职位→发送邮件」企业线是「注册→登录→发布招聘信息→删除招聘信息→修改企业信息→浏览求职者简历→发送邮件」管理员线则是「管理个人信息、单位信息、招聘信息、求职信息、友情链接」。这三条线的好处在分工彻底。求职者只会操作到求职相关页面招聘企业只能维护自己的公司和职位管理员不碰业务数据只做审核。老式 JSP 项目没有 Spring Security 这类权限框架靠的是三个独立的登录入口加 session 区分角色理解了这一点后面看登录代码时就不会乱。2.3 从模块图反推 JSP 页面清单文档里的模块图是文字流程图没有给出完整页面清单。按模块功能和命名习惯我会把它反推成下面这套页面作为代码还原时的目录结构参考JSP 页面对应功能需要的登录态index.jsp首页三个登录入口和两个注册入口无studentLogin.jsp个人求职登录无studentRegister.jsp个人求职注册无companyLogin.jsp企业招聘登录无companyRegister.jsp企业注册无adminLogin.jsp管理员登录无studentCenter.jsp个人中心发布/删除求职信息、改资料个人companyCenter.jsp企业中心发布/删除招聘信息、改资料企业adminManage.jsp管理员后台管理界面管理员这套页面清单不用照抄但它能帮你在拿到文档后迅速确定要写多少个 JSP、每个 JSP 的职责边界。当年做这类毕设最常见的问题就是图省事把登录、注册、管理全塞进一个页面最后改一处动全身后面排查时非常痛苦。3. 六张数据库表还原建表 SQL、字段语义与关联关系一次理清3.1 六张表的职责划分文档第三章把数据库设计成了六张表分别是个人求职信息表tb_sjob、企业信息表tb_company、用户信息表tb_student、企业发布招聘信息表tb_cjob、管理员用户表tb_admin、友情链接表tb_flink。先看它们的职责边界表名角色核心字段用途tb_student个人用户账号sname、password、realname、resume个人登录凭证与基础档案tb_sjob个人求职广告sname、job、specialty、emolument、ptime个人发布的求职意向tb_company企业账号cname、password、name、address、resume企业登录凭证与资料tb_cjob企业招聘广告cname、job、specialty、emolument、atime企业发布的招聘信息tb_admin管理员admin、password后台登录tb_flink友情链接name、address首页外部链接位值得注意个人账号表和个人求职信息表是分开的tb_student 管「你是谁」tb_sjob 管「你想找什么工作」企业同理。这是一种把用户画像和业务数据解耦的设计哪怕是毕设这个拆分思路也值得在论文里写一笔。3.2 按原文档字段补全的建表 SQL文档给出了每张表的字段、类型和大小但没有给可直接执行的建表语句。我按 SQL Server 语法补全了一份建库名可以叫 recruit。注意原文档没有明确主键下面补 SQL 时我把用户名设为主键你也可以改成自增 id看个人习惯。-- 个人用户信息表sname 是登录名也兼作主键 CREATE TABLE tb_student ( sname VARCHAR(20) PRIMARY KEY, password VARCHAR(50) NOT NULL, name VARCHAR(50), age INT, sex BIT, birthday DATETIME, school VARCHAR(50), specialty VARCHAR(50), knowledge VARCHAR(20), email VARCHAR(50), resume TEXT );这段 SQL 里我把 password 设成了 NOT NULL原论文没写这个约束但登录功能必须有密码加上更合理。sex 用 BIT 是典型的 SQL Server 布尔写法值为 0 或 1页面端显示成「男/女」这个类型别乱改成 INT改了就偏离原设计。-- 企业信息表cname 是企业登录名resume 存企业简介 CREATE TABLE tb_company ( cname VARCHAR(20) PRIMARY KEY, password VARCHAR(50) NOT NULL, name VARCHAR(50), email VARCHAR(50), tel VARCHAR(20), manage VARCHAR(20), address VARCHAR(100), resume TEXT );企业表的 manage 字段是「从事行业」属于企业画像和招聘广告表里的 specialty 语义不同行业是企业的固定属性职位专业是每条招聘广告的动态属性。写代码时不要混淆这两个字段的取值来源。-- 个人求职信息表jobid 自增ptime 是发布时间 CREATE TABLE tb_sjob ( jobid INT IDENTITY(1,1) PRIMARY KEY, sname VARCHAR(20) NOT NULL, specialty VARCHAR(50), job VARCHAR(50), emolument VARCHAR(50), ptime DATETIME DEFAULT GETDATE(), atime DATETIME, other VARCHAR(200) );-- 企业发布招聘信息表 CREATE TABLE tb_cjob ( jobid INT IDENTITY(1,1) PRIMARY KEY, cname VARCHAR(20) NOT NULL, specialty VARCHAR(50), job VARCHAR(50), emolument VARCHAR(50), ptime DATETIME DEFAULT GETDATE(), atime DATETIME, other VARCHAR(200) );这两张广告表的字段几乎对称sname/cname 记录发布者job 记录岗位名称emolument 记录薪水ptime 是发布时间atime 是截止时间。我给 ptime 补了 DEFAULT GETDATE()原文档没提这个默认值如果不加插入时忘记传时间字段就会得到 NULL 或 1900-01-01页面显示出来很难看。3.3 字段设计里的两个坑薪水用 varchar、外键靠逻辑关联原系统把 emolument 定义成 VARCHAR(50) 而不是数字类型。乍看不规范但放到毕设场景里是合理取舍招聘信息里的薪水往往是「3000-5000」「面议」这类文本用数字类型反而要额外处理符号和区间。答辩时如果被问到「为什么薪水不用 INT」就用「薪资本质是展示文本包含区间和面议varchar 更贴合业务展示」作答比硬解释成数据类型失误要稳。另一个坑在外键。tb_sjob 的 sname 和 tb_company 的 cname 在业务上是外键但原文档没有建立真正的 FOREIGN KEY 约束只靠程序逻辑保证。这其实是老式 JSP 项目的常见状态——建表时省约束写入时靠代码判断用户是否存在。带来的问题是如果两个账号同名注册不做校验就会产生脏数据。代码里必须做两步注册时先查重发布信息时从 session 取值而不是让用户手填 sname/cname。4. 核心代码还原Conn 连接类、登录验证与 JSP 乱码处理4.1 补全 Conn 类的完整写法文档第四章给出了 Conn 类的开头部分只写到 static Statement stmt没有给完整方法。按当时 JSP 项目的通行写法我补全成一个标准的数据库连接工具类。import java.sql.*; public class Conn { private static Connection con; private Statement stmt; // 返回一个数据库连接 public static Connection getConnection() { try { // SQL Server 2000 时代的驱动类名与连接串 // Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver); // 升级到 sqljdbc 后改用下面两行 Class.forName(com.microsoft.sqlserver.jdbc.SQLServerDriver); String url jdbc:sqlserver://localhost:1433;DatabaseNamerecruit; String user sa; String pwd 123; con DriverManager.getConnection(url, user, pwd); } catch (Exception e) { e.printStackTrace(); } return con; } // 执行查询返回结果集 public ResultSet executeQuery(String sql) { try { stmt con.createStatement(); return stmt.executeQuery(sql); } catch (SQLException e) { e.printStackTrace(); return null; } } // 关闭连接顺序很重要先关结果集再关语句最后关连接 public void close() { try { if (stmt ! null) stmt.close(); if (con ! null) con.close(); } catch (SQLException e) { e.printStackTrace(); } } }注意两块。第一Class.forName 的作用是注册 JDBC 驱动旧代码里必须写这一行如果你用的是新版本 sqljdbc 驱动驱动类名会从 com.microsoft.jdbc.sqlserver.SQLServerDriver 变成 com.microsoft.sqlserver.jdbc.SQLServerDriver连接串也要从 jdbc:microsoft:sqlserver:// 改成 jdbc:sqlserver://。第二close 顺序要严格反着来先结果集、再 Statement、最后 Connection我看到很多翻车现场是把 con 先关了再关 stmt结果抛空指针。4.2 登录验证用 PreparedStatement 而不是字符串拼接原文档没有给出登录验证代码但这类 JSP 项目最常见的登录写法就是「提交表单 → 查表 → 判断结果 → 写 session」。我一般会在 DAO 类里实现 checkLogin用 PreparedStatement 而不是字符串拼接原因看代码就明白。public boolean checkStudentLogin(String sname, String password) { String sql SELECT COUNT(*) FROM tb_student WHERE sname? AND password?; try (Connection con Conn.getConnection(); PreparedStatement ps con.prepareStatement(sql)) { ps.setString(1, sname); ps.setString(2, password); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { return rs.getInt(1) 0; } } } catch (SQLException e) { e.printStackTrace(); } return false; }用问号占位符的意义在于防 SQL 注入。如果写成 String sql SELECT COUNT(*) FROM tb_student WHERE sname sname AND password password 用户输入一个带引号的用户名就能改写整个 SQL 语句PreparedStatement 会把输入当纯数据处理这也是答辩时最容易被问到的安全考点。连接用 try-with-resources 是后来 Java 7 的写法老环境如果卡在 JDK 1.5 就改回手动 close。登录成功后的状态管理按角色区分 session 的 key。个人登录成功执行 session.setAttribute(student, sname)企业登录成功执行 session.setAttribute(company, cname)管理员登录成功执行 session.setAttribute(admin, admin)。每个受保护的页面顶部都要先判断对应 session 是否为空为空就 response.sendRedirect(index.jsp) 或直接 forward 回登录页。这套写法虽然原始但足够支撑毕设演示中的权限隔离需求。4.3 JSP 中文乱码三处编码必须统一中文乱码是老 JSP 项目的高频问题根源是三处编码不一致。第一处是 JSP 文件头pageEncoding 要声明成实际保存的编码第二处是 HTTP 响应的 contentType要显式写 charset第三处是请求参数解码POST 提交的中文需要在获取参数前调用 request.setCharacterEncoding。三处统一用 UTF-8 基本不会再乱。连接串里的字符集参数也和乱码有关如果数据库排序规则是 Chinese_PRC_CI_ASUTF-8 传输一般没问题。5. 避坑清单JSP 老毕设从文档到跑通最常见的五个坑5.1 数据库连不上驱动类名和连接串必须配套现象Tomcat 启动不报错但一登录就抛 ClassNotFoundException 或 SQLExceptionNo suitable driver found。原因文档里的代码是按 SQL Server 2000 时代写的驱动类名是 com.microsoft.jdbc.sqlserver.SQLServerDriver连接串是 jdbc:microsoft:sqlserver:// 开头现在网上能下载到的驱动基本都是 sqljdbc 系列类名和 URL 协议全变了。解决要么费劲找 2000 年代的旧驱动要么按 4.1 节把 Class.forName 和连接串一起升级到新版本两条路选一条走混着用一定报错。5.2 SQL Server 实例没开 TCP/IP 和混合认证现象驱动类和连接串都对但报 Connection refused 或 Login failed for user sa。原因SQL Server 默认可能只开了 Shared Memory 协议JDBC 走的是 TCP/IP 1433 端口另外 sa 账号需要 SQL Server 和 Windows 混合认证模式才能用账号密码登录。解决用 SQL Server Configuration Manager 启用 TCP/IP 协议重启 SQL Server 服务再用 Management Studio 把服务器认证模式改成 Mixed Mode给 sa 设好密码。查 1433 端口是否通可以用 telnet 或 netstat 确认。5.3 Tomcat 启动失败8080 端口被占用现象Tomcat 启动后 2 秒就自动停止日志里写着 Address already in use: JVM_Bind。原因443、8080、8005 端口被其他进程占用了最常见的是另一个 Tomcat 实例或开发工具内置服务器。解决用 netstat -ano | findstr 8080 找到占用进程的 PID去任务管理器结束它不想结束就直接改 Tomcat 安装目录下 conf/server.xml 里的 Connector port把 8080 改成 8081同时把 8005 关闭端口也改掉避免和别的服务冲突。5.4 数据库里中文全变成了问号现象注册信息在页面上正常一写入数据库就变成 ??重新查询显示乱码。原因连接串没指定字符编码数据库排序规则又不是 UTF-8SQL Server 连接串里要显式加 useUnicodetruecharacterEncodingUTF-8。解决先确认 JSP 三处编码都统一为 UTF-8再在连接串末尾追加字符集参数最后检查数据库排序规则。这一步顺序不要反过来页面编码没统一就调数据库往往改完还是乱。5.5 修改一个功能要牵动三个 JSP 文件现象想改一下删除求职信息的功能结果 personalCenter 页面、deleteJob.jsp、DBUtil 三处都要动改完还报 null。原因业务代码全部散落在 JSP 里没有 DAO 层也没有把 JavaBean 独立出来。解决按第 4 章的方式把数据库操作收敛到 DAO 类里JSP 页面只负责调用和展示不要直接写 JDBC 代码。这是个重构建议但对毕设答辩很加分——评审老师看到 JSP 里只有业务调用没有 SQL 拼接印象分会明显不同。6. 把它变成能演示的毕设环境版本对照与答辩动线6.1 环境版本怎么选文档年代的 JDK 是 1.5Tomcat 是 5.xSQL Server 是 2000这套东西现在几乎没法直接跑。我用过的最稳组合是 JDK 1.8 Tomcat 8.5/9.0 SQL Server 2005 及以上或者用 MySQL 替代因为 1.8 兼容老代码的语法Tomcat 8/9 的 Servlet 版本能跑 JSP 老项目而且没有 Tomcat 10 的 jakarta 命名空间问题。如果学校评审机器上只装了 MySQL连接串就改成 jdbc:mysql://localhost:3306/recruit?useUnicodetruecharacterEncodingUTF-8驱动类改成 com.mysql.cj.jdbc.Driver代码其余部分基本不动。6.2 答辩演示动线提前在库里预置一套演示数据一个管理员账号 admin一个企业账号 demo_company 带两条招聘信息一个学生账号 demo_student 带一条求职信息。演示时的推荐顺序是先以学生登录发一条求职信息再切企业登录浏览简历并发邮件最后管理员登录审核那两条新数据。这套动线覆盖了系统的所有核心功能也正好对应文档第三章的三条功能线评审老师按论文结构核对你实际系统时每一步都能对上号。我从这类老毕设文档里踩过的最大教训是拿到手别急着跑先核对「数据库版本 JDBC 驱动 连接串协议」三件套是否匹配再动手建表。当年我照着文档抄了个旧连接串折腾一整晚才反应过来驱动已经换代了。从那以后我每接手一份 JSP 老项目都会强制走一遍这个对齐流程十分钟就能判断出问题出在环境还是代码。希望帮到你。本文还有配套的精品资源点击获取
返回列表