
简介面向毕业设计场景的影视创作论坛系统完整项目资料包基于JavaEE与JSP技术构建覆盖从需求分析、系统设计、编码实现到部署答辩的完整流程适合计算机相关专业学生及JavaWeb学习者用于毕设参考与实战演练。压缩包内共18个文件整体约151MB包含源代码zip、SQL数据库脚本与MDF/LDF数据库文件、项目报告与任务书doc/docx、答辩PPT、多张功能界面截图以及3段部署辅导视频mp4文件类型覆盖开发、文档、演示与部署各环节结构清晰便于按需查阅。已有101人下载学习。借助这些材料可深入理解基于Servlet、JSP、JDBC的经典JavaWeb分层开发模式掌握论坛系统中登录注册、电影海报管理、影评发布、后台审核等核心模块的编码实现同时项目报告完整记录了中期检查、任务书与设计实现文档结合视频可快速搭建Tomcat环境并导入数据库有效提升毕业设计的完成质量与答辩表现。1. 影视创作论坛系统为什么这个毕设选题到现在还有人抢着做每年毕业设计选题季影视创作论坛系统总是热度不减。你可能觉得JSP已经是老技术了为什么还值得选实际上这个题目踩中了毕业设计的核心诉求技术栈是学校老师最熟悉的资料沉淀足够多系统边界清晰工作量可衡量。一套完整的JSPServletMySQL论坛系统从用户注册、视频发布、评论互动到后台管理覆盖了Java Web开发的主干知识点——会话管理、数据库操作、文件上传、分页查询、面向对象设计每一个都有明确的验收点。这篇笔记要讲的就是这套系统的完整落地路径怎么搭环境、怎么建库建表、核心功能怎么写、部署时最容易在哪翻车、答辩前怎么验证功能。适合正在做同类毕设选题、想快速跑通全流程并且能讲清楚设计思路的人——新手可以跟着一步步复现已经写了一半的人也能对着参数和避坑清单自查。2. 环境与项目骨架JDK、Tomcat、MySQL和IDE的选型组合2.1 技术栈选型JSPServletJavaBean三层结构为什么够用影视创作论坛系统的核心是内容发布与用户互动这类业务用JSPServlet就能干净地实现。常见的分层方式是JSP页面负责展示Servlet接收请求并控制跳转JavaBean封装业务逻辑和数据访问。相比Spring Boot全家桶这种三层结构在答辩时不容易被追问底层原理问倒每一条请求路径都能直接说出来浏览器发请求→Servlet接收→调用业务类→JDBC操作MySQL→返回结果到JSP渲染。技术选型的版本搭配我一般这样定JDK 1.8、Tomcat 8.5或9.0、MySQL 5.7或8.0。JDK 1.8是兼容性最稳的Tomcat 8.5对应Servlet 3.1规范支持JSP 2.3对老项目兼容好。MySQL 5.7资料多8.0功能新但连接驱动要选对。IDE用Eclipse for Java EE或IDEA Ultimate都行Eclipse导入项目更直接IDEA对JSP的代码补全更友好。接口连数据库用JDBC直连就够不用引入MyBatis——毕设答辩时JDBC的每个步骤都能拆开讲反而加分。2.2 环境变量与Tomcat配置的三个关键参数环境搭建看起来是体力活但三个位置配错会浪费一晚上。第一是JAVA_HOME必须指向JDK安装根目录不是bin目录第二是CATALINA_HOME指向Tomcat根目录第三是Path里要同时追加%JAVA_HOME%\bin和%CATALINA_HOME%\bin。配好后在命令行执行java -version和catalina version验证两个命令都通过再进下一步。Tomcat的启动参数里默认的JVM内存对这个小系统足够不需要调catalina.bat里的JAVA_OPTS。需要改的是端口——如果你本机8080被占了编辑conf/server.xml把Connector节点的port属性改掉同时注意URIEncodingUTF-8这个属性要显式加上否则GET请求的中文参数到后端会乱码。MySQL这边连接时在JDBC URL后面拼useUnicodetruecharacterEncodingutf8useSSLfalse这是整篇笔记里最重要的一个参数组合少了任何一个字符数据库里的中文就可能是问号。2.3 Web项目的标准目录结构与web.xml配置在IDE里新建Dynamic Web Project后目录结构要按规范整理。src下放Java源码按包名划分com.forum.servlet、com.forum.dao、com.forum.entity、com.forum.util。WebContent下放JSP页面和静态资源WEB-INF里放web.xml和lib目录。JSP页面不要直接放到WEB-INF里——那样URL访问会变复杂公共页面比如header、footer可以放WEB-INF/include里用jsp:include引用。web.xml是Servlet映射的注册中心以登录功能为例?xml version1.0 encodingUTF-8? web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd version3.1 display-nameFilmCreationForum/display-name welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list servlet servlet-nameLoginServlet/servlet-name servlet-classcom.forum.servlet.LoginServlet/servlet-class /servlet servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login/url-pattern /servlet-mapping servlet servlet-nameCharacterFilter/servlet-name servlet-classcom.forum.util.CharacterFilter/servlet-class /servlet servlet-mapping servlet-nameCharacterFilter/servlet-name url-pattern/*/url-pattern /servlet-mapping /web-app这段配置做了三件事声明首页为index.jsp把/login这个URL路径绑定到LoginServlet类注册了一个字符编码过滤器拦截所有请求。写过滤器的目的是统一处理POST请求的中文乱码。url-pattern用/*表示对所有路径生效注意不是//只匹配根路径。tomcat版本不同时web-app头的schema版本要对应Tomcat 8.5用3.1Tomcat 9用4.0配错会启动报错或提示Unknown version。3. 数据库设计与文件上传影视内容的数据模型怎么立住3.1 用户、视频、评论、点赞的四张核心表设计影视创作论坛的核心数据可以收敛成四张表用户表、视频表、评论表、点赞表。视频表是主体——这里的“视频”不只是视频文件本身还包含标题、简介、封面图、分类、发布时间、播放量等字段。系统刚起步时不要过度设计把字段控制在答辩能讲清楚的范围里表多了反而是负担。一个常见的设计错误是把视频文件存成BLOB字段直接喂给MySQL文件大了数据库会变得很臃肿备份和迁移都痛苦。推荐的设计是把视频文件存在服务器磁盘的指定目录数据库只存文件的相对路径。前端展示时拼出完整URL访问。这样数据库体积小视频文件也好单独管理。创作用户与视频是1:N关系用户与评论是1:N用户与点赞表用联合唯一索引避免重复点赞。下面这段SQL可以直接照着建库CREATE DATABASE IF NOT EXISTS film_forum DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; USE film_forum; CREATE TABLE t_user ( uid INT PRIMARY KEY AUTO_INCREMENT COMMENT 用户ID, username VARCHAR(50) NOT NULL UNIQUE COMMENT 登录用户名, password VARCHAR(255) NOT NULL COMMENT 密码建议MD5后存入, nickname VARCHAR(50) COMMENT 昵称, avatar VARCHAR(255) COMMENT 头像路径, role INT DEFAULT 0 COMMENT 0普通用户 1管理员, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB COMMENT 用户表; CREATE TABLE t_video ( vid INT PRIMARY KEY AUTO_INCREMENT COMMENT 视频ID, uid INT NOT NULL COMMENT 发布者ID, title VARCHAR(100) NOT NULL COMMENT 视频标题, description TEXT COMMENT 简介, video_url VARCHAR(255) NOT NULL COMMENT 视频文件路径, cover_url VARCHAR(255) COMMENT 封面图路径, category VARCHAR(30) COMMENT 分类剧情/纪录/动画等, play_count INT DEFAULT 0 COMMENT 播放量, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, CONSTRAINT fk_video_user FOREIGN KEY (uid) REFERENCES t_user(uid) ) ENGINEInnoDB COMMENT 视频表; CREATE TABLE t_comment ( cid INT PRIMARY KEY AUTO_INCREMENT, vid INT NOT NULL, uid INT NOT NULL, content VARCHAR(500) NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, CONSTRAINT fk_comment_video FOREIGN KEY (vid) REFERENCES t_video(vid), CONSTRAINT fk_comment_user FOREIGN KEY (uid) REFERENCES t_user(uid) ) ENGINEInnoDB COMMENT 评论表; CREATE TABLE t_like ( id INT PRIMARY KEY AUTO_INCREMENT, vid INT NOT NULL, uid INT NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_vid_uid (vid, uid), CONSTRAINT fk_like_video FOREIGN KEY (vid) REFERENCES t_video(vid), CONSTRAINT fk_like_user FOREIGN KEY (uid) REFERENCES t_user(uid) ) ENGINEInnoDB COMMENT 点赞表;注意几个细节utf8mb4比utf8多支持emoji评论里出现表情符号不会报错密码字段长度设255因为MD5加密后是32位但如果后期改用加盐哈希长度不够就要改表外键约束一定加上答辩时主外键关系是必考题。评论表和点赞表都引用了t_user和t_video删除用户或视频时要处理关联数据否则会因外键约束删除失败——我一般在前台屏蔽删除操作后台做逻辑删除加状态字段而不是物理删除省掉一堆级联麻烦。3.2 数据库连接工具类JDBC直连与连接池的选择论坛系统里每个页面请求几乎都要查数据库连接管理写不好系统一上并发就卡死。JDBC直连最简单每操作一次就DriverManager.getConnection()然后finally里关连接——毕设项目推荐这种写法逻辑清楚答辩能讲清。连接池比如Druid能提升性能但引入后要多配一个配置文件如果不是性能测试相关选题直连足够。package com.forum.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/film_forum ?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai; private static final String USER root; private static final String PASSWORD 123456; static { try { Class.forName(com.mysql.jdbc.Driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } public static void close(Connection conn, java.sql.Statement stmt, java.sql.ResultSet rs) { try { if (rs ! null) rs.close(); } catch (SQLException e) { e.printStackTrace(); } try { if (stmt ! null) stmt.close(); } catch (SQLException e) { e.printStackTrace(); } try { if (conn ! null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }serverTimezoneAsia/Shanghai是MySQL 8.0必须加的参数不加会报Server time zone异常。Class.forName在JDBC 4.0之后可以省略但写上更稳兼容老版本驱动。PASSWORD直接写在代码里对毕设没问题但如果项目要上生产环境得改成从配置文件读取。关闭资源时注意顺序先关ResultSet再关Statement最后关Connection反了会报连接泄漏。3.3 视频上传的路径规划与大小限制视频上传是影视创作论坛区别于普通论坛的核心功能。前端用一个input typefile namevideoFile表单后端Servlet接收后写入服务器目录。路径规划要分两层存储路径和访问路径。存储路径放在Tomcat的webapps/ROOT/upload/video/下用yyyyMMdd按日期分子目录避免单目录文件过多。文件名用UUID 原扩展名重命名防止中文文件名和重名覆盖。// UploadVideoServlet.java 核心片段 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); String savePath getServletContext().getRealPath(/) upload/video/; File dir new File(savePath); if (!dir.exists()) dir.mkdirs(); DiskFileItemFactory factory new DiskFileItemFactory(); // 临时文件缓冲区小于1MB的文件直接进内存超过的写磁盘 factory.setSizeThreshold(1024 * 1024); ServletFileUpload upload new ServletFileUpload(factory); // 单个文件最大500MB总大小限制1GB upload.setFileSizeMax(500L * 1024 * 1024); upload.setSizeMax(1024L * 1024 * 1024); try { ListFileItem items upload.parseRequest(request); String title null; FileItem videoItem null; for (FileItem item : items) { if (item.isFormField()) { if (title.equals(item.getFieldName())) { title new String(item.getString().getBytes(ISO-8859-1), UTF-8); } } else if (videoFile.equals(item.getFieldName())) { videoItem item; } } if (title null || videoItem null) { request.setAttribute(msg, 标题和视频文件都不能为空); request.getRequestDispatcher(/publish.jsp).forward(request, response); return; } String ext videoItem.getName().substring(videoItem.getName().lastIndexOf(.)); String fileName UUID.randomUUID().toString().replace(-, ) ext; videoItem.write(new File(dir, fileName)); // 构造Video对象调用DAO写入数据库video_url存相对路径 // video.setVideoUrl(upload/video/ fileName); } catch (Exception e) { e.printStackTrace(); request.setAttribute(msg, 上传失败 e.getMessage()); request.getRequestDispatcher(/publish.jsp).forward(request, response); } }表单里有普通字段和文件字段混合时parseRequest返回的ListFileItem要把这两类分开处理通过isFormField()判断。文件大小限制不能只靠后端建议前端也加提示否则用户选了个2GB的文件传输半天才发现被拦截体验很糟糕。videoItem.write()要求目标目录已存在所以前面mkdirs()必须执行。文件名用UUID重命名后数据库里存相对路径前端用video src${pageContext.request.contextPath}/upload/video/xxx.mp4访问。提示upload目录最好在发布前手动清空一次把测试时的废弃视频删掉否则答辩演示时打开文件目录一片混乱影响观感。4. 核心功能落地登录、发布、评论和搜索的JSP实现4.1 登录与会话管理MD5加密和Session超时设置登录模块是每个评委必看的第一个功能点。实现思路是登录表单提交到LoginServletServlet调用UserDAO查询用户名和密码是否匹配匹配则把用户信息写入Session跳转到首页不匹配则回到登录页并提示错误。密码存储不要用明文常见做法是MD5加密后入库。MD5本身可逆但毕设答辩被问到“密码安全”时能说出“MD5 Salt”已经比大多数同学想得深。// LoginServlet.java 核心逻辑 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username request.getParameter(username); String password request.getParameter(password); // 对用户输入做MD5后与库中密文比较 String encrypted MD5Util.md5(password); UserDAO dao new UserDAO(); User user dao.findByUsernameAndPassword(username, encrypted); if (user ! null) { HttpSession session request.getSession(); session.setAttribute(loginUser, user); session.setMaxInactiveInterval(30 * 60); // 30分钟无操作自动过期 response.sendRedirect(request.getContextPath() /index.jsp); } else { request.setAttribute(msg, 用户名或密码错误); request.getRequestDispatcher(/login.jsp).forward(request, response); } }用sendRedirect还是forward是有讲究的登录成功用重定向避免刷新页面时重复提交表单登录失败用forward这样msg属性可以在login.jsp上通过${msg}显示。setMaxInactiveInterval(30 * 60)设置的是Session空闲超时时间单位是秒意思是用户30分钟不操作就自动过期重新操作时需要再登录。注意Session里存的是User对象JSP页面里用${sessionScope.loginUser.nickname}取出昵称展示。4.2 分页查询和搜索首页视频列表与关键词匹配首页的视频列表不能一次性查出所有记录数据量大了页面会卡。分页是必做项。分页参数两个当前页码page和每页条数pageSize。SQL用LIMIT offset, pageSize实现offset (page - 1) * pageSize。同时用一条SELECT COUNT(*)查总条数算出总页数。搜索功能在视频标题字段上用LIKE %关键词%模糊匹配注意SQL注入——用PreparedStatement的setString方法传参数不要拼接字符串。// VideoDAO.java 分页查询核心方法 public ListVideo findPage(int page, int pageSize, String keyword) { ListVideo list new ArrayList(); String sql SELECT v.*, u.nickname FROM t_video v LEFT JOIN t_user u ON v.uid u.uid ; if (keyword ! null !keyword.trim().isEmpty()) { sql WHERE v.title LIKE ? ; } sql ORDER BY v.create_time DESC LIMIT ?, ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { int index 1; if (keyword ! null !keyword.trim().isEmpty()) { ps.setString(index, % keyword %); } ps.setInt(index, (page - 1) * pageSize); ps.setInt(index, pageSize); try (ResultSet rs ps.executeQuery()) { while (rs.next()) { Video v new Video(); v.setVid(rs.getInt(vid)); v.setTitle(rs.getString(title)); v.setVideoUrl(rs.getString(video_url)); v.setCoverUrl(rs.getString(cover_url)); v.setPlayCount(rs.getInt(play_count)); v.setNickname(rs.getString(nickname)); list.add(v); } } } catch (SQLException e) { e.printStackTrace(); } return list; }LEFT JOIN把发布者的昵称直接带出来避免在页面再查一次用户表。LIMIT ?在MySQL里可以用占位符但要注意LIMIT ? , ?两个参数的顺序是offset在前pageSize在后传反了分页就错乱。try-with-resources语法JDK 7可以自动关闭Connection和PreparedStatement代码比手动finally关闭简洁。JSP页面上用c:forEach遍历列表展示分页导航的页码链接形如index.jsp?page2keyword${keyword}——注意keyword也要回传否则翻到第二页搜索条件就丢了。4.3 评论功能的关联查询与JSP展示评论功能考察的是“多表关联”这个核心知识点。一条视频的评论列表需要查出评论者昵称和头像涉及t_comment和t_user两表。评论提交时后端Servlet要同时拿到当前登录用户的uid和视频的vid插入评论表。展示时按时间倒序最新评论在最上面。%-- videoDetail.jsp 中评论列表展示 --% c:forEach items${commentList} varc div classcomment-item div classcomment-user img src${c.avatar} classavatar alt头像/ span${c.nickname}/span /div div classcomment-content${c.content}/div div classcomment-time fmt:formatDate value${c.createTime} patternyyyy-MM-dd HH:mm:ss/ /div /div /c:forEach需要引入JSTL标签库才能在JSP里用c:forEach和fmt:formatDateWEB-INF/lib下放jstl-1.2.jar页面顶部加% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %和% taglib prefixfmt urihttp://java.sun.com/jsp/jstl/fmt %。没有JSTL的话只能用% for %脚本片段页面里全是Java代码答辩时看着就不像正规做法。评论列表的查询SQL在VideoDAO里加一个方法SELECT c.*, u.nickname, u.avatar FROM t_comment c LEFT JOIN t_user u ON c.uid u.uid WHERE c.vid ? ORDER BY c.create_time DESC和分页查询一样用PreparedStatement传vid。5. 典型部署流程与避坑指南从本机跑到能在答辩现场演示5.1 导出WAR包与Tomcat部署的完整操作答辩前把项目部署到评委能访问的地址是刚需至少要保证在本机Tomcat上能一键启动。开发阶段用IDE直接Run on Server但这不算部署——答辩前要练习用WAR包部署。在Eclipse里右键项目Export→WAR file勾选“Export source files”会把Java源码也打进去IDEA里是Build→Build Artifacts→选择xxx:war。生成的WAR包有个命名讲究film_forum.war放在Tomcat的webapps目录下启动Tomcat后会自动解压成film_forum文件夹访问路径是http://localhost:8080/film_forum/。如果你不想让URL里带项目名可以把WAR包改名为ROOT.war部署明天用http://localhost:8080/直接访问——但要注意这样会影响Tomcat自带的管理页面建议还是保留项目名前缀。Linux服务器上的部署是一样的用scp把WAR包传到/opt/tomcat/webapps/下重启Tomcat即可。数据库方面要记得在目标服务器上执行建库SQL并且修改DBUtil里的数据库地址、用户名、密码。Windows和Linux的路径分隔符不同代码里存文件路径时用File.separator代替硬编码的/或\否则跨平台会翻车。5.2 避坑清单JSP项目的5个高频问题JSP项目跑不起来的原因往往不是核心逻辑而是环境与配置。下面这5个问题覆盖了我自己调试时翻车的场景按频率从高到低排。第1个GET请求中文乱码而POST请求正常。现象是搜索框输入“动画”提交后页面显示乱码或查不到结果。原因是URIEncoding没配置Tomcat 8默认的GET编码是UTF-8但老版本可能是ISO-8859-1编码不一致导致中文参数到后台已经变成乱码。解决在server.xml的Connector节点加URIEncodingUTF-8重启Tomcat生效。另外如果你用了request.setCharacterEncoding(UTF-8)它只对POST请求体有效对GET的URL参数无效——这正是“POST正常GET乱码”的原因。第2个启动Tomcat报404页面找不到。现象是访问http://localhost:8080/film_forum/出现404。原因通常是WAR包没被正确解压或项目名写错。解决确认webapps目录下是否有film_forum文件夹如果没有说明WAR包没有正常展开检查Tomcat日志logs/catalina.out有没有报错如果文件夹存在确认URL里的大小写与项目名一致。Tomcat对大小写敏感。第3个ClassNotFoundException: com.mysql.jdbc.Driver。现象是第一次访问数据库时直接500。原因是MySQL驱动JAR没有放到WEB-INF/lib目录下。解决把mysql-connector-java-5.1.49.jar对应MySQL 5.7或mysql-connector-j-8.0.33.jar对应MySQL 8.0放进lib目录并刷新项目。注意驱动类名不同——5.x是com.mysql.jdbc.Driver8.x是com.mysql.cj.jdbc.DriverDBUtil里的Class.forName写错会报类找不到。第4个数据库连接报Public Key Retrieval is not allowed。现象是MySQL 8.0连接失败。原因是MySQL 8默认使用caching_sha2_password认证插件客户端首次连接需要获取公钥。解决JDBC URL加allowPublicKeyRetrievaltrue或者创建一个用mysql_native_password插件的用户。第5个明明登录成功了刷新后却退出登录。现象是登录后跳转首页正常一刷新就回到登录页。原因有几种可能Session超时设得太短比如设了1分钟用自己的电脑测试不够用浏览器禁用了Cookie导致SessionId无法维持或者是session.setAttribute和session.getAttribute的key不一致。解决确认代码里key统一为loginUser把setMaxInactiveInterval设到30分钟以上检查浏览器设置里的“阻止所有Cookie”选项是否打开——打开后Tomcat的JSESSIONID写不进浏览器Session就“立不住”。5.3 答辩演示环境的部署模拟答辩现场的电脑大概率不是你自己的所以要提前演练一遍“裸机部署”。我建议答辩前至少做三次完整演示第一次用自己的电脑第二次用一台只装了JDK和Tomcat的干净虚拟机第三次只保留WAR包和一个视频MP4不看笔记从头部署一遍。部署文档要写清楚三个信息JDK版本、Tomcat版本、MySQL版本以及各自的安装路径。最简单的演示方案是把数据库导出成.sql文件答辩现场执行source film_forum.sql导入数据不要现场建库手工敲SQL——有几个提前准备几个预置账号一个管理员、一个普通用户演示时用账号登录进去展示功能比现场注册省时间。部署过程中最容易出问题的还是数据库导入。建议用mysqldump导出时加--default-character-setutf8mb4参数否则导出的SQL文件在别的机器上用默认字符集导入中文全部变成乱码。导入后立刻查一条中文数据确认编码正常再开始部署WAR包——顺序不能反先有数据再启动应用否则首次访问可能因为空数据库报错。6. 答辩前一天的验收方法过一遍这8个验证点就够了答辩不是现场找bug而是演示你系统“能干什么”。前一天按下面这个清单过一遍每一项都有明确的通过标准。我吃过亏的地方是会挑自己最顺的流程反复演示结果评委问“如果用户输错密码怎么办”现场操作反而出了岔子——所以要把正常路径和异常路径分开演练。验证点操作方式通过标准用户注册新账号注册并登录注册成功自动登录或跳转登录页无服务端报错用户登录正确/错误密码各一次错误密码提示文案正确密码进入首页视频发布上传一个小于50MB的MP4上传成功列表页能看到新视频播放器能播放评论功能登录后在视频详情页发评论评论即时显示页面不刷新搜索功能搜索已知标题中的关键词结果列表准确分页后关键词保留分页功能翻到第2页URL参数正确数据不重复不遗漏权限控制未登录直接访问发布页URL被拦截并重定向到登录页后台管理管理员账号登录进入管理页能查看用户和视频列表第7项“权限控制”是最容易被忽略的。很多JSP项目只在页面上隐藏了“发布”按钮没在Servlet层做拦截——直接输入/publish.jsp地址还是能访问这是一个重大漏洞。最简单的方案是写一个LoginFilter在web.xml里拦截/publish.jsp、/uploadVideo和/admin/*检查Session里有没有loginUser没有就跳转到登录页public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpSession session request.getSession(false); User user (session ! null) ? (User) session.getAttribute(loginUser) : null; if (user null) { ((HttpServletResponse) resp).sendRedirect(request.getContextPath() /login.jsp); return; } chain.doFilter(req, resp); // 已登录继续访问目标资源 }这段过滤器代码的写法是JSP项目里典型的权限控制方案。request.getSession(false)拿Session时不会新建Session——这是有意为之的因为未登录用户没必要创建一个空会话。管理员功能要单独校验role字段普通用户即使绕过了登录直接访问/admin.jsp也会被拦截。评委如果追问“怎么防止SQL注入”你就指向所有DAO方法都是PreparedStatement预编译问“怎么防止上传恶意文件”就提setFileSizeMax限制大小和只允许指定扩展名.mp4、.jpg、.png白名单校验问“怎么优化查询性能”就提分页加索引——create_time和title字段加普通索引在数据量大时有明显效果。把每个功能点对应的设计意图和异常处理讲清楚比代码写得多更重要。这是我带过几轮毕业设计后最深的体会希望帮到你。本文还有配套的精品资源点击获取