ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Java JSP智能网络教学系统毕设全解析:从MySQL建表到Tomcat部署避坑

Java JSP智能网络教学系统毕设全解析:从MySQL建表到Tomcat部署避坑 简介一份基于JSP的智能网络教学系统完整项目源码主要面向Java Web课程设计、毕业设计及实训开发者。项目整合教师管理、学生管理、课程资源发布、在线作业与测验等典型功能模块可作为理解Servlet/JSP及MVC分层架构的实战案例。压缩包共672个文件整体约3.56MB涵盖JSP页面、CSS样式、JavaScript脚本、GIF/JPG图片素材、数据库SQL脚本、Java类文件及少量DOCX/TXT说明文档其中JSP负责动态页面逻辑CSS与JS控制界面样式和前端交互SQL文件用于初始化教学业务数据表。目前已有124人浏览学习适合需要快速搭建教学管理平台或系统梳理Java Web项目结构的学习者。资源附带Eclipse工程配置、classpath及数据库建表脚本导入开发环境即可参考部署同时页面模板和素材较完整便于二次定制功能模块。1. Java基于JSP的智能网络教学系统是什么一个毕设题目的真实技术版图坦白说看到“Java基于JSP的智能网络教学系统的实现mysql.zip”这个标题第一反应像十年前的毕设选题。但搜索热度告诉我这件事每年都有大量人在做JSPServletMySQL是Java Web最经典的三层组合“智能网络教学系统”是一个在线学习平台——教师建课、布置作业、发起考试学生选课、交作业、查成绩管理员管用户和权限。标题里的.zip说明项目以压缩包形式分发里面通常是源码、SQL脚本和部署说明。这套栈看着旧但能把HTTP请求、Session、JDBC连接池这些底层概念讲透。适合正在选毕设题目的学生也适合想补JSP/Servlet原理、之后再切换Spring Boot的开发者。别急着嫌它过时跑通它你收获的东西比想象多。2. 把JSPServletMySQL的选型逻辑讲透这套技术栈为什么还是毕设首选2.1 JSP的职责边界页面渲染与业务逻辑该放在哪先拆解JSP的本质。一个JSP文件在第一次被访问时Tomcat会把它翻译成对应的Java源文件再编译成class执行。翻译出来的类继承HttpServlet所以JSP的生命周期——初始化、service、销毁——与Servlet完全一致。这个知识点也是Java面试题里Java Web部分的常客把“JSP是Servlet的视图封装”这句话讲清楚比背一堆标签更顶用。但JSP能写Java代码不代表应该到处写。智能教学系统的页面大致分成三套学生端有课程列表、作业提交、考试成绩教师端有课程管理、作业批改、考试出题管理端有用户管理和数据统计。如果每页都塞% %脚本片段项目三个月后自己都回不来。我的做法是严格按MVC分工Servlet接收请求、调Service、决定跳转JSP只负责渲染用EL表达式和JSTL标签把数据变成页面。Java代码只允许出现在两类地方后端.java文件以及JSP头部的page指令和taglib声明。遇到必须写逻辑的场景优先问一句“这个逻辑能不能下沉到Servlet再放进request里”能就绝不留在页面上。按这个思路教学系统的典型请求流程是浏览器提交表单 → web.xml或注解映射到Servlet → Servlet调DAO读MySQL → 结果放进request域 → forward到JSP渲染。这套链路建立起来以后加一个“学生选课”功能就是复制同样的模式不需要重新理解架构。2.2 MySQL表设计用户、课程、成绩三张核心表的最小模型先写建表脚本。这是整个zip包里最值得先看的部分也是答辩时最容易被追问的部分。CREATE DATABASE IF NOT EXISTS teaching_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE teaching_system; CREATE TABLE t_user ( user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID, username VARCHAR(50) NOT NULL UNIQUE COMMENT 登录名, password VARCHAR(64) NOT NULL COMMENT 密码摘要建议MD5或SHA-256, real_name VARCHAR(50) DEFAULT NULL COMMENT 真实姓名, role TINYINT NOT NULL DEFAULT 2 COMMENT 角色1管理员 2教师 3学生, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表; CREATE TABLE t_course ( course_id INT AUTO_INCREMENT PRIMARY KEY, course_name VARCHAR(100) NOT NULL, teacher_id INT NOT NULL COMMENT 授课教师关联t_user.user_id, course_desc TEXT, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, CONSTRAINT fk_course_teacher FOREIGN KEY (teacher_id) REFERENCES t_user(user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT课程表; CREATE TABLE t_score ( score_id INT AUTO_INCREMENT PRIMARY KEY, student_id INT NOT NULL, course_id INT NOT NULL, score DECIMAL(5,2) DEFAULT 0.00 COMMENT 成绩默认值为0, exam_time DATETIME DEFAULT NULL, UNIQUE KEY uk_stu_course (student_id, course_id), CONSTRAINT fk_score_student FOREIGN KEY (student_id) REFERENCES t_user(user_id), CONSTRAINT fk_score_course FOREIGN KEY (course_id) REFERENCES t_course(course_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT成绩表;这段脚本解决了几个常见问题。第一统一utf8mb4字符集能存中文和特殊符号比utf8更省心。第二成绩用DECIMAL(5,2)而不是FLOAT避免浮点误差DEFAULT 0.00对应了很多人搜过的“mysql设置默认值为0”——成绩没录入时显示0.00而不是NULL页面取值更安全。第三外键显式命名并启用很多毕设只画ER图不建物理外键答辩时被问“主外键在哪”就卡壳了。字段类型也有讲究。角色用TINYINT存1/2/3比存字符串高效权限判断写user.getRole()3头也不疼。时间用DATETIME不用TIMESTAMP因为教学系统的数据基本都是历史记录不涉及时区换算DATETIME范围更大且不会被2038年问题波及。username字段加了UNIQUE约束登录查询能直接命中唯一索引不用额外建索引。如果你想体现“智能”两个字可以再加一张t_answer_record表记录学生每次作业的选择题答案字段包括answer_id、student_id、course_id、question_id、user_answer、is_correct。有了这张表就能做错题统计、章节薄弱点分析这一张表的分量比写一堆形容词大得多。2.3 连接池参数DBCP还是C3P0拿连接和还连接都有讲究JSP项目里最常见的连接池是DBCP和C3P0现在新起的HikariCP性能更好但在老项目里用得少。这三者的对比如下对比项DBCPC3P0HikariCP配置复杂度低properties即可中偏好XML配置低代码或properties默认空闲回收有有有性能中中高老JSP项目普及度高高低毕设推荐推荐推荐可用但少见不是越新越好。毕设项目讲的是稳定和可解释DBCP的配置最简单下面这段db.properties是最小可用配置。# db.properties放在src目录下由DBUtil加载 jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/teaching_system?useUnicodetruecharacterEncodingutf8mb4useSSLfalseserverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.password123456 # DBCP连接池参数 dbcp.initialSize5 dbcp.maxActive20 dbcp.maxIdle10 dbcp.minIdle2 dbcp.maxWait3000 dbcp.validationQuerySELECT 1 dbcp.testOnBorrowtrue逐个讲参数含义。initialSize5指Tomcat启动时池里先建5条连接避免第一个用户访问时现场建连maxActive20是池子最多给20条连接超过就要等待maxWait3000是借连接的最大等待毫秒数超过3秒直接抛异常而不是无限等下去否则并发一高整个Tomcat线程池会被占死。testOnBorrowtrue表示从池里借连接前先执行validationQuery验证MySQL的wait_timeout默认8小时会回收空闲连接如果没有这条验证借出来的可能是一条死连接。连接池用到的驱动类要看版本。MySQL 5.x的驱动类是com.mysql.jdbc.DriverMySQL 8.x要用com.mysql.cj.jdbc.Driver同时URL里要加serverTimezoneAsia/Shanghai否则报时区错误。很多zip包里带的都是老驱动如果你本机是MySQL 8.x连不上先查这个。还有一个必踩的坑用DriverManager.getConnection拿连接不算用连接池。正确写法是预先创建BasicDataSource所有业务代码都从数据源里borrow和return。下面这段是DBUtil的骨架import org.apache.commons.dbcp2.BasicDataSource; import java.sql.Connection; import java.sql.SQLException; public class DBUtil { private static BasicDataSource dataSource; static { dataSource new BasicDataSource(); dataSource.setDriverClassName(com.mysql.jdbc.Driver); dataSource.setUrl(jdbc:mysql://localhost:3306/teaching_system?useUnicodetruecharacterEncodingutf8mb4useSSLfalse); dataSource.setUsername(root); dataSource.setPassword(123456); dataSource.setInitialSize(5); dataSource.setMaxTotal(20); dataSource.setMaxWaitMillis(3000); dataSource.setValidationQuery(SELECT 1); dataSource.setTestOnBorrow(true); } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }代码里最需要记住的是这个类只负责出连接不负责还连接。用完连接的业务代码必须调用close()而BasicDataSource的close是归还池子而不是真关连接。忘记close的后果是连接泄漏后面第4章会细讲。另一个细节是不要在JDBC代码里提交事务让事务边界留在Service层DBUtil保持无状态。3. 从zip包到跑通系统解压、导入、配置与最小登录全流程3.1 用IntelliJ IDEA导入JSP项目从zip到可运行工程毕设zip包的解压有几个老生常谈的注意点。解压路径不能带中文和空格否则IDEA的构建和Tomcat的部署偶尔会抽风。解压后先看一眼目录结构常见的项目结构大致是这样路径作用src/Java源码按包分好web/ 或 WebContent/JSP页面、静态资源web/WEB-INF/web.xmlWeb部署描述符Servlet映射web/WEB-INF/lib/第三方jar依赖teaching_system.sql数据库初始化脚本打开IntelliJ IDEA用Open定位到解压后的目录。如果目录里没有pom.xmlIDEA会以普通项目模式打开这时需要手动把src标记为Sources Root把web目录标记为Web Resources Root。操作路径是右键目录 → Mark Directory as → Sources Root。之后打开File → Project Structure → Facets确认Web Resource Directory指向web目录没有则新增一个Web Facet。这点不做干净菜单栏里不会有运行Tomcat的按钮。老一点的项目经常是Eclipse结构导入后乱报错是正常的不要慌。检查Project Structure → Libraries把WEB-INF/lib下的全部jar包选中加入。如果lib目录下没有mysql驱动和jstl后面登录和页面渲染必然报ClassNotFoundException。驱动版本尽量和本机MySQL匹配。做完这些再配置TomcatEdit Configurations → 加号 → Tomcat Server → LocalDeployment里选war exploded artifactApplication Server填本机Tomcat路径。这里强调一个IDEA新版本容易踩的坑新版IDEA默认不自动附带Tomcat集成插件需要确认Plugins里Tomcat相关插件可用。如果运行按钮是灰的多半是从来没创建过Tomcat Server配置先到Edit Configurations里加一个Local实例再回来看。传统JSP项目不需要Maven也不需要Spring只要Tomcat配好就能直接跑。3.2 配置Tomcat与MySQLJDBC驱动、建库脚本与DBUtilMySQL本地安装完成并启动服务后用Navicat for MySQL或者命令行连接实例。我习惯先用Navicat建好连接再执行SQL脚本因为可视化界面能直接看到表的字段注释和外键关系方便核对是哪一张表出了问题。执行2.2的建表脚本后插入三行测试账号方便登录流程调试。INSERT INTO t_user (username, password, real_name, role) VALUES (admin, MD5(123456), 系统管理员, 1), (teacher01, MD5(123456), 张老师, 2), (student01, MD5(123456), 李同学, 3); INSERT INTO t_course (course_name, teacher_id, course_desc) VALUES (Java Web程序设计, 2, 面向对象与Servlet);密码用MD5(123456)而不是明文123456是答辩加分项。要注意MD5函数是MySQL内置的返回32位十六进制字符串与Java端用MessageDigest算出来的结果一致前提是两边都不加盐。如果Java端算的MD5和数据库对不上先检查大小写再检查编码。这里有个容易被忽略的点t_course表里teacher_id2是与t_user表自关联的外键插入课程数据前教师账号必须存在外键约束会在你顺手删用户的时候提醒你。然后准备JDBC驱动。如果没有对应版本的jar从本机Maven仓库找一个mysql-connector-java放进WEB-INF/lib。MySQL 5.7用5.1.x驱动MySQL 8.0用8.0.x驱动混合使用最常见的问题是ClassNotFoundException或者Communications link failure。驱动放好后DBUtil里配置的连接参数与第2章一致启动Tomcat时不再报驱动加载错误就算通了。补充一句MySQL服务的启动确认Windows下直接看服务列表里MySQL状态是否是“正在运行”Linux下systemctl status mysqld确认。要是服务没起来后面所有数据库相关的报错都不必查代码先解决服务本身。这类问题占了“数据库连不上”排查的一半。3.3 先跑通登录再扩展Servlet与DAO的最小配合登录是第一个需要打通全部链路的功能。目标很简单用户提交用户名密码登录成功进主页失败留在登录页并显示错误。先把LoginServlet写出来。WebServlet(/login) public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding(UTF-8); String username req.getParameter(username); String password MD5Util.getMD5(req.getParameter(password)); UserDao dao new UserDao(); User user dao.findByUsernameAndPassword(username, password); if (user ! null) { req.getSession().setAttribute(loginUser, user); resp.sendRedirect(index.jsp); } else { req.setAttribute(error, 用户名或密码错误); req.getRequestDispatcher(login.jsp).forward(req, resp); } } }代码里有两个关键决策。第一个是请求参数用req.getParameter(username)这个name必须与login.jsp里input nameusername完全一致差一个字母都拿不到值。第二个是成功用sendRedirect重定向到index.jsp失败用forward转发回login.jsp。重定向会让浏览器地址栏变成index.jsp刷新页面不会重新提交表单转发则保留request域里的error消息而重定向会丢失request域数据所以错误信息必须放在request里且用转发放session里再用重定向也行但要注意清理。配套的UserDao只干一件事查询匹配的用户代码如下public class UserDao { public User findByUsernameAndPassword(String username, String password) { String sql SELECT * FROM t_user WHERE username? AND password?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, password); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { User u new User(); u.setUserId(rs.getInt(user_id)); u.setUsername(rs.getString(username)); u.setRealName(rs.getString(real_name)); u.setRole(rs.getInt(role)); return u; } } } catch (SQLException e) { e.printStackTrace(); } return null; } }DAO里的try-with-resources是值得养成的习惯Connection、PreparedStatement、ResultSet三样都能自动close不用在finally里手动判断null少写一堆样板代码也堵住了连接泄漏的口子。SQL用占位符?而不是字符串拼接既能防SQL注入又让数据库可以复用执行计划。登录跑通之后课程管理、作业提交、成绩录入这些功能全部照这个模式复制换的只是SQL和页面架构不需要动。提示登录跑通后先备份一份zip包或提交一次版本后续改坏了有后悔药。毕设项目改到崩溃重来的情况实在太常见。4. JSP项目避坑手册本地演示前必查的5个翻车点4.1 中文乱码从请求到响应的三层编码链现象页面正常显示但提交的中文姓名变成问号数据库里中文正常页面读出来却是乱码。原因JSP项目的编码链路有三段——请求参数编码、JSP页面字符集、数据库连接字符集。任何一段不一致就乱码。常见于只设置了JSP页面的contentType忘了连接URL里的characterEncoding。解决第一JSP文件头用% page contentTypetext/html; charsetUTF-8 pageEncodingUTF-8%且文件本身以UTF-8保存IDEA右下角可以确认文件编码。第二连接URL带上characterEncodingutf8mb4。第三在web.xml里注册编码过滤器强制每个请求都按UTF-8解码。过滤器代码很简短但必须映射到/*。filter filter-nameencodingFilter/filter-name filter-classcom.teaching.filter.EncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter filter-mapping filter-nameencodingFilter/filter-name url-pattern/*/url-pattern /filter-mappingpublic class EncodingFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding(UTF-8); resp.setCharacterEncoding(UTF-8); chain.doFilter(req, resp); } }排查乱码的顺序有个土办法先在页面alert一下输入框的值看前端有没有乱再在Servlet里打印req.getParameter看请求到后端有没有乱最后直接查数据库表看落库有没有乱。三段定位哪段开始乱就从哪段修。大多数情况是连接URL漏了characterEncoding或者MySQL表的字符集被建成了latin1改表字符集的命令是ALTER TABLE t_user CONVERT TO CHARACTER SET utf8mb4;。4.2 Error 2002 (HY000): MySQL连不上的排查顺序现象Tomcat启动后第一次访问登录接口控制台报java.sql.SQLException: Unable to connect或者错误信息形如ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock。原因这个报错要分场景。如果报错里带through socket /tmp/mysql.sock说明客户端试图走Unix socket连本地MySQL常见于Linux下的JSP项目本质是连接串用了localhost而MySQL的socket文件路径对不上如果带through TCP/IP说明走的是3306端口服务没启、端口被占、账号密码错都可能。解决按这个顺序排查每次只改一个变量。第一步确认MySQL服务在运行Windows看服务管理器Linux看systemctl status mysqld第二步用命令行客户端试连mysql -u root -p -h 127.0.0.1 -P 3306强制走TCP绕开socket文件问题能连上说明服务正常问题在你的项目配置第三步检查db.properties的URL、用户名、密码是否和本机一致特别是密码别照抄zip包里的默认值很多毕设包写死密码为123456本机改过密码就必挂。第四步查驱动版本MySQL 5.7用老驱动没问题MySQL 8.0必须用cj驱动加serverTimezone参数。还有一个容易被忽略的细节MySQL 8.0默认的认证插件是caching_sha2_password老版本驱动不认这个东西报Public Key Retrieval is not allowed。解决方法是URL加allowPublicKeyRetrievaltrue或者把用户的认证插件改回mysql_native_password两种选其一我一般选后者兼容性好。4.3 JSP里的Java代码太多页面越写越乱怎么收场现象课程列表JSP里有% for %循环、% if %判断甚至直接在页面里new DAO查数据库页面几百行改一个按钮要滚动半天一报错就是长长的空指针栈。原因这是JSP刚上手时的通病觉得既然JSP能写Java直接在页面里写最省事。问题在于JSP里的脚本片段混着HTML和SQL职责全揉在一起改一处崩三处。解决分两步收场。第一步把循环和判断换成JSTL标签引入taglib后c:forEach items${courseList} varc替代% for %用EL表达式输出属性页面立刻清爽一半。第二步把数据查询下沉到DAO、流程控制下沉到ServletJSP只留渲染。具体做法是Servlet里查好list放进request.setAttribute(courseList, list)JSP里只用JSTL读。迁移时一页一页来每页改完刷新验证再动下一页不要试图一次重写全部。面试或答辩时主动讲一句“我把脚本片段迁成了JSTL让页面更可维护”这比说“我把页面写得很漂亮”有说服力。4.4 打包部署传统JSP项目打war包的正确姿势现象本地跑得好好的要把项目发给老师或部署到服务器不知道war包怎么打。有人直接右键项目Export成war结果部署到Tomcat后404有人复制整个项目文件夹到webapps启动后访问地址不对。原因IDEA里直接运行用的是exploded目录不是标准war结构。没有Maven的普通JSP项目打包靠IDEA的Build Artifacts或者命令行jar工具很多人第一次摸黑操作。解决推荐用IDEA打warFile → Project Structure → Artifacts点加号新建Web Application: Exploded和Web Application: Archive两个artifact然后Build → Build Artifacts → 选Archive → BuildIDEA生成.war文件。拿到war放到Tomcat的webapps目录启动Tomcat自动解压部署访问路径是http://localhost:8080/war包名/。另一种方式是命令行在web目录下执行jar -cvf teaching_system.war .本质都是把WebContent内容打成标准zip并保留WEB-INF结构。这里顺带聊一个高频热问nginx支持jsp吗答案是不支持。nginx只托管静态资源JSP必须先由Tomcat翻译并编译成Servletnginx的常见用法是作为反向代理把动态请求转发给Tomcat的8080端口静态资源由nginx直接返回。如果部署时只有nginx没有TomcatJSP页面下载下来就是源码不会执行。4.5 连接池耗尽系统慢到像死机先查谁没还连接现象演示刚开始没问题点几个页面后越来越慢最后报Cannot get a connection, pool exhausted重启Tomcat好一会再过一阵又死。原因典型连接泄漏。某个查询方法里拿到连接后遇到异常提前return把close放在return之后的代码永远执行不到连接一条条流失池子被抽干。更隐蔽的是ResultSet没关虽然连接归还了但打开的结果集占用数据库游标长期累积也拖垮数据库。解决数据库访问统一收敛到DAO用try-with-resources管理Connection和Statement这是Java 7以后最可靠的写法在第3章的UserDao里已经示范过。如果用的是老代码至少把close写进finally块。排查泄漏有一个实用技巧在DBUtil里加一个统计字段getConnection时活跃数1close时-1定期打印活跃数。如果某个操作前后活跃数不回落那段代码就是泄漏点。我给学员演示时常用这招比一行行读代码快得多。DBCP本身也有日志开关开启后能看到借出和归还的记录但调试起来不如自己埋点直观。提示排查连接池问题时先把maxActive临时调小到5这样泄漏会在一两次请求后就暴露比调大日志次数更直接。5. 把这个教学系统做成能答辩的毕设三个进阶方向与验证清单5.1 三个值得投入的进阶点第一个是随机组卷在成绩表旁边加一张t_question表存题干、选项、难度、知识点出题时按难度比例从题库随机抽题页面用JSP展示考卷。这个功能实现成本低但讲解空间大能引出“随机算法和题库设计”的答辩话题。第二个是成绩可视化把t_score的数据按课程聚合在JSP页面里用条形图展示不需要引入前端框架用一点CSS撑高度就能做个简易柱状图。能讲清楚“数据从数据库到页面的整个链路”答辩老师一般很受用。第三个是三级权限控制在编码过滤器之后再加一个权限过滤器拦截/admin/、/teacher/路径未登录或角色不符的请求直接重定向到登录页。这样能顺理成章讲出Filter链是什么、拦截器和过滤器的区别这是Java Web面试里仅次于生命周期的考点。5.2 答辩前的回归验证清单验证项操作预期结果登录流程管理员、教师、学生各登一次跳转对应角色首页乱码回归新增一条含中文的课程名列表页正常显示中文连接池回收连续刷新登录页50次控制台无连接池报错权限拦截未登录直接访问教师管理URL被重定向到登录页数据备份用Navicat导出SQL再重新导入数据完整、外键约束不报错我自己的习惯是每次改动功能之前先跑一遍这三项能正常登录、能建课、能存成绩三个回归基线不动其他功能怎么改都不慌。把zip包跑起来只是开始能在此基础上换一张表、改一个流程、讲清楚一个参数才算真正把JSP这套东西接住了。希望这篇笔记能帮你少走我踩过的弯路让答辩顺利一些。本文还有配套的精品资源点击获取
返回列表