ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Java影视创作论坛开发实战:Spring Boot+MySQL设计与答辩指南

Java影视创作论坛开发实战:Spring Boot+MySQL设计与答辩指南 简介面向Java毕业设计选题的影视创作论坛完整项目包适用于本科或专科计算机相关专业学生完成课程设计、毕业设计及答辩准备。项目基于Java EE技术体系包含前台用户模块与后台管理模块覆盖影视作品展示、影评发表、用户管理、海报与电影信息维护等典型功能可作为学习SSH/SSM等框架整合与论坛类系统开发的参考案例。压缩包共17个文件大小约151.02MB主要包含源代码压缩包、MySQL数据库脚本及附加数据库文件、毕业论文Word文档、答辩PPT、项目开发任务书与中期检查表、三个MP4操作演示视频、项目截图和阅读说明涵盖从编码、部署、测试到论文撰写的完整材料。已有131人学习下载。这套资源可直接导入开发工具运行结合视频演示快速熟悉前后台操作流程并借助论文与PPT梳理设计与答辩思路适合需要完整毕设方案或希望快速上手同类项目的人群。1. 基于Java的影视创作论坛从答辩与源码角度看一个“该有却没做好”的选题“影视创作论坛”听起来比“学生管理系统”有画面感但它真正难住人的不是论坛本身而是四样交付物挤在同一个 zip 里论文、答辩 PPT、源代码、数据库、讲解视频。这五样东西要口径一致每一处截图和表名都能互相印证工作量远大于写功能。多数人栽在“论坛做完了论文里的 ER 图和数据库里的表对不上”“PPT 演示的功能在源码里找不到入口”。这里把“设计与实现”拆成一条可复现的路线先明确论坛的最小边界——用户、影视条目、帖子、评论、管理端再用 Spring Boot MyBatis MySQL 把这五件事做成带登录鉴权的完整闭环最后把论文、PPT、数据库脚本和讲解视频当作“另一套代码”来生产。整条路线可以脱离任何现成项目模板自己从空目录建出来也能用来反向检验你手头那份源码包是否完整、可运行、禁得起追问。2. 影视创作论坛的需求边界与数据库设计先定表再写代码2.1 论坛的最小可用功能集五张主表与三类角色影视创作论坛的核心不是“发帖”而是“围绕影视创作资源做内容沉淀”。业务上至少要有三个角色普通用户访客可浏览登录后发帖回帖、创作者上传影视作品条目、管理员审核内容、管理用户。围绕这三个角色最小可用功能集应当收敛为如下五个模块用户模块注册、登录、个人信息查看、密码修改。影视条目模块发布影视创作作品包含片名、类型、导演、简介、封面图。帖子模块基于影视条目的讨论帖包含标题、正文、发帖人、关联影视条目。评论模块帖子下的回复包含回复内容、回帖人、所属帖子。管理模块用户管理、影视条目审核、帖子置顶与删除。这五个模块落在数据库里就是五张核心表user、movie、post、comment、admin。把“管理员”单独建表而不是给user加role字段是为了在答辩时能讲清“为什么不用一张表”提示管理员与用户在权限、字段、生命周期上差异显著。管理员不需要注册接口、不需要头像、不会被用户列表分页展示单独建表可避免业务查询里到处WHERE role 1。真正设计表时还要补两张关联表movie_category影视类型避免type字段写死字符串和post_like帖子点赞演示多对多关系。后文会逐步建出来。2.2 建表语句的“答辩友好”写法注释、外键、索引三件套数据库设计在答辩环节是高频追问区。评委会看三件事表字段有没有业务注释外键关系是否和 ER 图一致常用查询是否走了索引。下面给一套可以直接建库的脚本数据库名film_forum字符集utf8mb4CREATE DATABASE IF NOT EXISTS film_forum DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE film_forum; CREATE TABLE user ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 用户ID, username VARCHAR(50) NOT NULL UNIQUE COMMENT 登录名, password VARCHAR(100) NOT NULL COMMENT 密码MD5加盐, nickname VARCHAR(50) DEFAULT NULL COMMENT 昵称, avatar VARCHAR(255) DEFAULT NULL COMMENT 头像URL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 注册时间 ) ENGINEInnoDB COMMENT普通用户表; CREATE TABLE movie ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 影视条目ID, title VARCHAR(100) NOT NULL COMMENT 影视名称, category_id INT NOT NULL COMMENT 类型ID关联movie_category, director VARCHAR(50) DEFAULT NULL COMMENT 导演, summary TEXT COMMENT 剧情简介, cover VARCHAR(255) DEFAULT NULL COMMENT 封面图URL, user_id INT DEFAULT NULL COMMENT 创建者ID关联user表, status TINYINT DEFAULT 1 COMMENT 审核状态0未通过1已通过, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_category (category_id), KEY idx_status (status) ) ENGINEInnoDB COMMENT影视创作条目表; CREATE TABLE post ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 帖子ID, movie_id INT NOT NULL COMMENT 关联影视条目, user_id INT NOT NULL COMMENT 发帖用户, title VARCHAR(100) NOT NULL COMMENT 帖子标题, content TEXT COMMENT 帖子正文, is_top TINYINT DEFAULT 0 COMMENT 是否置顶0否1是, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_movie (movie_id), KEY idx_user (user_id) ) ENGINEInnoDB COMMENT讨论帖表; CREATE TABLE comment ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 评论ID, post_id INT NOT NULL COMMENT 所属帖子, user_id INT NOT NULL COMMENT 评论用户, content VARCHAR(500) NOT NULL COMMENT 评论内容, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_post (post_id) ) ENGINEInnoDB COMMENT帖子评论表; CREATE TABLE admin ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 管理员ID, username VARCHAR(50) NOT NULL UNIQUE COMMENT 管理员账号, password VARCHAR(100) NOT NULL COMMENT 管理员密码 ) ENGINEInnoDB COMMENT管理员表; CREATE TABLE movie_category ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) NOT NULL UNIQUE COMMENT 类型名剧情、纪录片、动画 ) ENGINEInnoDB COMMENT影视类型表; CREATE TABLE post_like ( id INT PRIMARY KEY AUTO_INCREMENT, post_id INT NOT NULL, user_id INT NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_post_user (post_id, user_id) ) ENGINEInnoDB COMMENT帖子点赞表;建表脚本里每一项都有对应的答辩话术password不用VARCHAR(32)是因为 MD5 加盐后可能加长post_like的联合唯一键说明“一个用户对一帖只能点一次赞”movie.status字段直接支撑“审核”功能点的存在。这些细节在论文数据表设计章节能展开写在答辩 PPT 里也能做成一页“设计亮点”。2.3 从 ER 图反推需要补的关系多对多与级联策略五张主表建好后需要手动检查关系完整性。用户和影视条目是一对多一个用户可以发布多条影视条目影视条目和帖子是一对多帖子和评论是一对多用户和帖子是多对多通过post_like。这里有几个容易在论文和答辩中被追问的坑第一movie.user_id和post.user_id都引用同一张user表。ER 图上要画出两条不同的关系连线不能因为“都是 user_id”就合并成一条线。第二删除策略不能照抄“级联删除”的教科书写法。管理员删除一个用户时如果级联删除他的帖子那么帖子下的评论也连带消失数据恢复成本极高。常见的做法是软删除ALTER TABLE user ADD COLUMN deleted TINYINT DEFAULT 0 COMMENT 逻辑删除标记0否1是; ALTER TABLE post ADD COLUMN deleted TINYINT DEFAULT 0 COMMENT 逻辑删除标记0否1是;逻辑删除字段配合查询过滤器使用MyBatis 的where deleted 0全局追加或者用TableLogic注解若选用 MyBatis-Plus自动拼接。不搞物理外键、不设ON DELETE CASCADE这既是工程实践的主流做法也是论文“系统设计”章节可以写满两页的内容。3. 从零用 Spring Boot 搭出论坛骨架Maven、SSM、登录态一次说清3.1 技术选型为何是 Spring Boot 而非 SSM 手写配置影视创作论坛这类毕设项目候选人通常会有两个派别传统 SSMSpring SpringMVC MyBatisXML 配置和 Spring Boot。近年来的主流答辩团队几乎默认 Spring Boot原因是“减少非业务代码的篇幅把时间留给功能实现和论文撰写”。但注意不要让选型变成一句空话。要从“自动配置”和“起步依赖”两个机制展开讲。Spring Boot 的spring-boot-starter-web自动装配了 DispatcherServlet、内嵌 Tomcat、Jackson 消息转换器这就是为什么项目里没有web.xml和spring-mvc.xml也能跑通 HTTP 请求。MyBatis 配合spring-boot-starter-jdbc和mybatis-spring-boot-starter数据源由application.yml驱动。答辩时被问到“Spring 和 Spring Boot 什么关系”标准回答是“Spring Boot 是 Spring 的约定优于配置的封装底层还是 Spring IoC/DI”。我给出的最小工程结构如下Maven 坐标和 Java 包名保持统一前缀com.example.forumfilm-forum/ ├── pom.xml └── src/main/ ├── java/com/example/forum/ │ ├── ForumApplication.java │ ├── controller/ │ ├── service/ │ ├── mapper/ │ ├── entity/ │ └── config/ └── resources/ ├── application.yml └── mapper/pom.xml依赖里四个关键起步依赖缺一不可spring-boot-starter-webWeb 能力、mybatis-spring-boot-starter持久层、mysql-connector-j驱动、lombok简化实体类。注意mysql-connector-j在 Spring Boot 2.7.x 里坐标是mysql-connector-javaSpring Boot 3.x 开始改名com.mysql:mysql-connector-j写错版本会直接抛Cannot load driver class: com.mysql.cj.jdbc.Driver。3.2 一张application.yml理清数据库连接、端口、日志配置文件写得好不好直接决定演示时“换机器能否十分钟拉起”。答辩前换成自己电脑演示很常见配置里最忌讳把绝对路径、本机特殊端口写死。推荐如下配置server: port: 8080 servlet: context-path: /forum spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/film_forum?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 123456 servlet: multipart: max-file-size: 10MB max-request-size: 20MB mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.forum.entity configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl参数说明分三层第一层是 JDBC 连接串serverTimezoneAsia/Shanghai解决 MySQL 8.x 时区报错useSSLfalse避免本地演示证书报警第二层是 multipart 上传限制影视封面图一般在 2MB 以内10MB 上限已经够宽第三层是 MyBatis 两根关键配置map-underscore-to-camel-case把create_time自动映射为createTimeStdOutImpl让每条 SQL 打印到控制台——答辩演示时这个日志就是“查询数据库成功”的直接证据。3.3 登录鉴权不引入 Shiro用拦截器和 Session 做闭环毕业设计里做影视创作论坛评审最常追问的是“游客能看什么登录能做什么”。不用 Shiro、Spring Security 这种重框架用拦截器即可讲透权限控制。先定义一个登录拦截器Component public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { Object userId request.getSession().getAttribute(userId); if (userId null) { // 判断是否为Ajax请求前端跳转会失效 String requestedWith request.getHeader(X-Requested-With); if (XMLHttpRequest.equals(requestedWith)) { response.setStatus(401); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:401,\msg\:\请先登录\}); } else { response.sendRedirect(/forum/login); } return false; } return true; } }拦截器里有两个容易被忽视的细节。其一Ajax 请求不能sendRedirect否则前端拿到的是一整个 HTML 页面而不是 JSON 数据其二userId存在 Session不引入 Redis原因在于单机部署的论坛并发量有限Session 足以覆盖使用场景论文里“系统部署方案”一章也可以据此定调。注册拦截器要走WebMvcConfigurer而不是继承WebMvcConfigurationSupport否则会覆盖 Spring Boot 自动配置的静态资源映射。以下注册方式在 Spring Boot 2.x 、3.x 都通用Configuration public class WebConfig implements WebMvcConfigurer { Resource private LoginInterceptor loginInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns(/**) .excludePathPatterns( /login, /register, /movie/list, /movie/detail/**, /post/list, /post/detail/**, /css/**, /js/**, /images/**, /upload/** ); } }.excludePathPatterns括号里放的是游客可见接口和静态资源。影视条目列表、帖子详情允许匿名访问发表和评论一律拦截。这一组路径同时出现在论文“系统用例图”和答辩 PPT“权限设计”页里属于典型的“代码与文档互印”。3.4 用户注册与 MD5 加盐的三种做法选一种能讲清的就够用户密码存储是答辩里相对容易“翻车”的点不要一句“用了 MD5”就完事。搜索引擎里关于影视论坛的提问大量卡在“数据库里的密码是明文”“密码不能登录”说明大多数学生没有掌握加盐套路。推荐最容易被答辩老师接受的方案MD5 固定盐。先看一下核心实现public class Md5Util { private static final String SALT film_forum_2024; public static String encrypt(String password) { return DigestUtils.md5DigestAsHex((SALT password).getBytes(StandardCharsets.UTF_8)); } }DigestUtils.md5DigestAsHex来自 Spring 的spring-core不需要额外引包。固定盐不好吗对于论坛毕设完全够用但答辩老师如果追问“固定盐和随机盐的区别”要能接住话随机盐需要给user表加salt字段注册时生成随机串存入数据库登录校验时先查出该用户的盐再算 MD5。为了论文数据表不用返工建议二选一要么在 2.2 建表脚本里直接加salt字段要么就坚持固定盐不给自己挖坑。注册接口的 Service 层逻辑如下public boolean register(User user) { String username user.getUsername(); if (userMapper.findByUsername(username) ! null) { return false; } user.setPassword(Md5Util.encrypt(user.getPassword())); user.setNickname(StringUtils.hasText(user.getNickname()) ? user.getNickname() : username); return userMapper.insert(user) 0; }findByUsername依赖username的唯一索引插入前先查一次。这里故意不用“先 Insert 后捕获 DuplicateKeyException”的方式是为了让逻辑对新手更直白也方便在论文里画注册流程图时画成“查询 → 判断 → 插入”三步。登录逻辑与之对应userMapper.findByUsername查出来后比对密文。这里有一个加强演示效果的小改动登录失败时不要返回笼统的“用户名或密码错误”。在Controller里区分两种失败原因返回“用户名不存在”和“密码错误”旁观者能立刻看到代码在真实工作。4. 核心业务落地影视条目发布、帖子列表加分页、评论与点赞4.1 影视条目发布文件上传与表单提交的分离影视创作论坛与普通论坛最大的差异在于“影视条目先于帖子存在”。用户在“发布创作”页面填写片名、导演、简介并上传封面图提交后生成一条movie记录其他用户才能针对该条目发帖讨论。因此影视条目发布表单是一个标准的multipart/form-data请求。交互设计上要注意封面图上传与表单提交分离。常见做法是用户先选图前端立即调/upload接口把图片传到服务器成功后把返回的 URL 填进隐藏域最后随表单提交。这样好处是表单失败时不用重新传图也避免了大文件阻塞业务接口。上传接口实现如下PostMapping(/upload) public Result upload(RequestParam(file) MultipartFile file) { if (file.isEmpty()) { return Result.error(文件不能为空); } String originalFilename file.getOriginalFilename(); String ext originalFilename.substring(originalFilename.lastIndexOf(.)); String newFileName UUID.randomUUID().toString().replace(-, ) ext; String datePath new SimpleDateFormat(yyyyMMdd).format(new Date()); String dirPath uploadPath datePath; File dir new File(dirPath); if (!dir.exists()) { dir.mkdirs(); } String fullPath dirPath File.separator newFileName; try { file.transferTo(new File(fullPath)); } catch (IOException e) { return Result.error(上传失败); } String url /upload/ datePath / newFileName; return Result.success(url); }uploadPath是配置类里从application.yml读取的本地磁盘目录UUID.randomUUID()保证文件名不可预测日期子目录避免单个文件夹文件过多transferTo是 Spring 封装的 MultipartFile 落盘方法。使用绝对路径保存到磁盘返回的却是相对 URL再由 WebMvcConfigurer 里的资源映射把/upload/**指到磁盘目录Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String path uploadPath.replace(\\, /); registry.addResourceHandler(/upload/**) .addResourceLocations(file: path); }不这样映射前端img src/upload/20240701/xxx.jpg会 404。答辩前务必检查uploadPath末尾是否有斜杠Windows 的路径分隔符在资源映射里也要处理。4.2 帖子列表的 PageHelper 分页必须写清楚 count 与 pageNum 的坑论坛首页帖子列表、管理端用户列表都需要分页。用 PageHelper 是常见选择但也是 MyBatis 项目中报错频率最高的一环。引入依赖后Service 层代码public PageInfoPostVO getPostPage(Integer pageNum, Integer pageSize) { if (pageNum null || pageNum 1) { pageNum 1; } if (pageSize null || pageSize 0) { pageSize 10; } PageHelper.startPage(pageNum, pageSize); ListPostVO postList postMapper.selectPostList(); return new PageInfo(postList); }PageHelper.startPage后必须紧跟第一条查询语句中间插不得别的查询PageInfo里封装了total、pageNum、list等字段直接返回给前端即可不需要自己拼PageResult类。坑点在于如果selectPostList的 XML 里有多条 SQL或者同一个方法里先后调用两个 mapper 方法分页会把第二条查询也截断或作用到错误语句上。要规避把分页查询写成专用方法不在其中做关联赋值。用一个嵌套示例说明select idselectPostList resultMapPostVOMap SELECT p.id, p.title, p.content, p.create_time, u.nickname AS authorName FROM post p LEFT JOIN user u ON p.user_id u.id ORDER BY p.is_top DESC, p.create_time DESC /select这条 SQL 里不写LIMIT分页由 PageHelper 的拦截器自动拼接。注意服务层返回的PageInfo给前端时list中每条帖子要带“评论数量”。这个数字不能循环去查数据库要在同一条 SQL 里用子查询或 left join 聚合SELECT p.id, p.title, p.content, p.create_time, u.nickname AS authorName, (SELECT COUNT(*) FROM comment c WHERE c.post_id p.id) AS commentCount FROM post p LEFT JOIN user u ON p.user_id u.id ORDER BY p.is_top DESC, p.create_time DESC一条 SQL 完成主查询与统计避免 N1 查询问题。论文“性能优化”章节也能拿这页去写。4.3 发帖与回帖事务控制在两处必须加发帖和回帖的逻辑看起来只是insert两行但考虑论坛业务完整性两处必须加事务。第一处是发帖时同时更新影视条目下“帖子数”统计字段若movie表有post_count第二处是回帖时修改post表的last_reply_time。用Transactional注解不加任何参数默认就可以Transactional(rollbackFor Exception.class) public void addPost(Post post) { postMapper.insert(post); movieMapper.increasePostCount(post.getMovieId()); } Transactional(rollbackFor Exception.class) public void addComment(Comment comment) { commentMapper.insert(comment); postMapper.updateLastReplyTime(comment.getPostId()); }rollbackFor Exception.class是关键配置默认的Transactional只在 RuntimeException 时回滚捕获Exception后抛出的检查异常不会回滚。演示时想验证事务是否生效可以在addComment的第二行故意抛一个new RuntimeException()看comment表是否插入了脏数据。4.4 点赞功能联合唯一索引与 Redis 的取舍帖子点赞是影视创作论坛最容易“做重”也最容易“做砸”的功能。如果引入 Redis 做点赞需要额外处理缓存穿透、定时落库答辩时要是解释不清就麻烦。更稳妥的方案基于 MySQL 联合唯一索引 状态反转。post_like表已经有UNIQUE KEY uk_post_user (post_id, user_id)点赞逻辑就是先查是否存在若存在则删除若不存在则插入形成“点赞/取消点赞”的 toggleOverride Transactional(rollbackFor Exception.class) public boolean toggleLike(Integer postId, Integer userId) { PostLike like likeMapper.findByPostIdAndUserId(postId, userId); if (like ! null) { likeMapper.deleteById(like.getId()); postMapper.decreaseLikeCount(postId); return false; } PostLike newLike new PostLike(); newLike.setPostId(postId); newLike.setUserId(userId); likeMapper.insert(newLike); postMapper.increaseLikeCount(postId); return true; }post表加一个like_count字段展示列表时直接从帖子行读出排序时可以ORDER BY like_count DESC这就是一个没有 Redis 的“热度排序”雏形。答辩时话术是“本系统作为课程设计并发量在百级单机 MySQL 完全够用引入 Redis 反而增加缓存一致性维护成本。”这个取舍要写在论文的设计模式或系统架构章节而不是藏在代码注释里。5. 管理端报表与数据可视化把数据库里的数字变成答辩加分项5.1 用 ECharts 做用户增长、影视分类占比、帖子热度统计管理端不能只有增删改查。一张“数据概览”页把统计图表放上去PPT 截图会立刻显得信息量大。ECharts 是加载 CDN 还是本地 jar答辩现场很可能断网必须把echarts.min.js下载到resources/static/js/目录下。三个图表对应三张表的聚合查询第一个是“近 7 日用户注册趋势”。后端统计接口返回形如[{date: 2024-06-25, count: 3}, ...]SQL 写法SELECT DATE(create_time) AS date, COUNT(*) AS count FROM user WHERE create_time DATE_SUB(CURDATE(), INTERVAL 7 DAY) GROUP BY DATE(create_time) ORDER BY date前端拿到date和count两个数组交给 ECharts 的 line 图。需要处理“某天没有注册用户”造成的时间断点用Calendar在 Java 侧把缺失日期补 0而不是让图表缺一块。第二个是“影视分类占比”。直接 JOINmovie_category与movie表SELECT c.name, COUNT(m.id) AS cnt FROM movie_category c LEFT JOIN movie m ON c.id m.category_id AND m.status 1 GROUP BY c.id, c.name注意LEFT JOIN后条件m.status 1要写在ON子句而不是WHERE否则LEFT JOIN的名存实亡没有影视条目的分类会被排除。第三个是“帖子回复数 TOP10”。这个需求很能体现 SQL 功底SELECT p.id, p.title, COUNT(c.id) AS reply_count FROM post p LEFT JOIN comment c ON c.post_id p.id GROUP BY p.id, p.title ORDER BY reply_count DESC LIMIT 10LEFT JOIN确保 0 回复的帖子也进榜LIMIT 10在前端图表上表现最直观。答辩讲解点落在“关联查询 分组聚合 排序”三个 SQL 知识点上而不是 ECharts 本身。5.2 Excel 导出与列表打印给管理端加一个数据处理出口管理端的影视条目列表往往要导出 Excel。用 Apache POI 写HSSFWorkbook.xls兼容旧版 Office或者XSSFWorkbook.xlsx逻辑很短public void exportMovieList(HttpServletResponse response) throws IOException { ListMovie movieList movieMapper.selectAll(); XSSFWorkbook workbook new XSSFWorkbook(); Sheet sheet workbook.createSheet(影视条目); String[] headers {ID, 影视名称, 导演, 类型, 审核状态, 创建时间}; Row headerRow sheet.createRow(0); for (int i 0; i headers.length; i) { headerRow.createCell(i).setCellValue(headers[i]); } for (int i 0; i movieList.size(); i) { Row row sheet.createRow(i 1); Movie movie movieList.get(i); row.createCell(0).setCellValue(movie.getId()); row.createCell(1).setCellValue(movie.getTitle()); row.createCell(2).setCellValue(movie.getDirector()); row.createCell(3).setCellValue(movie.getCategoryName()); row.createCell(4).setCellValue(movie.getStatus() 1 ? 已通过 : 未通过); row.createCell(5).setCellValue(movie.getCreateTime().toString()); } response.setContentType(application/vnd.openxmlformats-officedocument.spreadsheetml.sheet); response.setHeader(Content-Disposition, attachment;filenamemovie_list.xlsx); workbook.write(response.getOutputStream()); workbook.close(); }这段代码的答辩亮点有两个。一是表头“审核状态”从0/1翻译成中文展示了对数据字典的理解二是Content-Disposition设置文件下载名Spring Boot 不需要额外配置静态资源就能输出为附件。导出接口放在管理端控制器的/admin/movie/export路径下受管理员拦截器保护。5.3 管理端权限再收紧Admin 拦截器与菜单可见性管理端和前台不能共用一套拦截规则。常见做法是新增一个AdminInterceptor检查 Session 里的adminIdComponent public class AdminInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { Object adminId request.getSession().getAttribute(adminId); if (adminId null) { response.sendRedirect(/forum/admin/login); return false; } return true; } }而WebConfig里单独给/admin/**路径配置注册registry.addInterceptor(adminInterceptor) .addPathPatterns(/admin/**) .excludePathPatterns(/admin/login);这里有个顺序问题LoginInterceptor的拦截路径是/**它也会拦截/admin/**导致管理员未登录会被先踢到前台登录页。这时需要给LoginInterceptor增加排除路径或者在preHandle里判断 URI 前缀。常用做法是把/admin/login也加进LoginInterceptor的excludePathPatterns并让 AdminInterceptor 提前注册保证/admin/**先经过 AdminInterceptor。前端菜单可见性用 Thymeleaf 的 Session 判断th:block th:if${session.adminId ! null} a href/admin/index管理后台/a /th:block管理端入口只在管理员登录后显示游客可以靠猜测路径访问/admin/index但会被拦截器拦回登录页。这个设计在答辩时要主动演示一次让评委看到“即便知道后台地址也进不去”的安全闭环。6. 论文、答辩 PPT、数据库脚本的“同源校验”技巧6.1 从数据库脚本反推论文 ER 图杜绝文档与实现脱离大部分答辩翻车都源于“论文画了一张理想化 ER 图数据库里却是另一套表”。同一个影视创作论坛论文第 3 章实体关系图里没有post_like表数据库却建了论文里movie表有click_count字段用SHOW CREATE TABLE一看根本没有。要避免这种问题强烈建议从建表脚本反向画图。用 MySQL 工具DataGrip、Navicat、DBeaver 均可连接film_forum库右键数据库选择“逆向表到模型”让工具按真实外键和列关系生成 ER 图再把图复制到论文或答辩 PPT。如果表之间没有物理外键工具生成的图不会有连线反而暴露问题。这时手工在 ER 图上补关系线条并对照中文注释写实体属性列表实体属性关系userid, username, password, nickname, avatar, create_time, deleted发布 movie发表 post发表 commentmovieid, title, category_id, director, summary, cover, user_id, status属于 user拥有 postpostid, movie_id, user_id, title, content, is_top, create_time属于 movie拥有 comment被 user 点赞commentid, post_id, user_id, content, create_time属于 post发表者 user把这张表直接写进论文的数据库设计章节每一位评委会的追问都有了明确的回答起点。6.2 答辩 PPT 的功能结构图、数据库关系图与演示流程对齐PPT 上出现的每一张功能截图都必须能在当前版本的源代码里找到对应页面。三个常见失控场景分别是PPT 上有“用户收藏”功能源码里没有favorite表PPT 的运行效果图是从旧版本截的界面文案与现在的代码不符PPT 里的数据统计用的是 Excel 假数据现场演示时数据库里根本不是那组数。对齐方法分两步。第一步PPT 页脚加“演示环境说明”写清 MySQL 版本、JDK 版本、演示数据的初始账号。第二步把所有 PPT 截图放进一个screenshots/目录截图时地址栏要保留http://localhost:8080/forum/...路径。答辩 PPT 里“系统功能结构图”建议画成三层用户端、创作者端、管理端。用户端含注册、登录、浏览、搜索、评论创作者端含影视条目发布、帖子管理管理端含用户管理、影视审计、评论管理、数据统计。这张图必须和 2.1 节的最小功能集一一对应不要出现任何多余模块。数据表截图只放三张即可movielist表结构post_like表数据展示联合唯一键以及一个多表联查的 SQL 结果。太少显得做作太多显得没有取舍。6.3 压缩包内文件命名与 README 的检查要点拿到手的压缩包通常名为Java毕业设计——基于Java的影视创作论坛的设计与实现论文答辩PPT源代码数据库讲解视频.zip解压后的组织方式直接影响第一印象。推荐在压缩包内用如下目录结构01-论文/ 02-答辩PPT/ 03-源代码/ 04-数据库/ 05-讲解视频/ README.txt检查点依次为数据库目录下至少包含一个.sql文件最好同时有schema.sql和data.sql源代码目录可编译pom.xml在根目录README.txt不少于三行包含 JDK 版本、MySQL 版本、演示账号讲解视频时长不小于 5 分钟且画面里出现过localhost:8080/forum。如果是自己打包上传.zip内不要混入回收站文件、Thumbs.db、.DS_Store和target/目录。这些杂物在 Windows 解压后会让审查者更快失去耐心。压缩前用mvn clean清掉构建产物再打 zip。6.4 答辩演示时“从压缩包到系统上线”的 5 分钟路径演示环节最怕的不是功能有问题而是从启动到可交互的路径太长、步骤太多。建议把整个演示收敛到一条“5 分钟从压缩包复原系统”的路径上并把每一步做成开头索引页解压.zip打开03-源代码用 IDEA 打开pom.xml所在目录等待 Maven 依赖下载完成。在 MySQL 里执行04-数据库/forum.sql完成建库、建表、插入演示数据。修改application.yml中数据库密码为本地密码本人演示电脑建议直接把 root 密码写成本机一致减少现场修改成本。启动ForumApplication.java控制台出现Tomcat started on port(s): 8080后访问/forum。用 README 里的预置管理员账号登录先走“用户管理”再打开“数据统计”页展示 ECharts 图表。前 4 步的成功要素其实是 3.2 节里配置文件的规范化表达——数据库账号密码集中在一个文件分页与上传路径无绝对路径依赖。走到第 5 步看到图表后整个验收已经过了大半不必把论坛所有按钮都演示一遍。6.5 讲解视频的录制建议3 段结构应对不同审查视角讲解视频并非毕业论文答辩才对你有价值在作品提交、网盘分享、跨校区审查场景下录制质量往往比压缩包里的论文更能说明代码的真实性。录像建议用 OBS 或 Windows 自带录屏画质选 1080p 即可帧率 30 帧。时长推荐 8 到 15 分钟过长会稀释重点过短又显得没有内容。录制前用“分镜脚本”把要展示的路径写在便签上不要临场想操作。比较好的三段式结构是第一段约 2 分钟展示环境与系统启动。用 IDEA 打开源代码运行ForumApplication浏览器访问/forum完成用户登录。画面里要出现控制台日志中的 SQL 打印直接证明系统不是纯静态页面。第二段约 6 分钟走核心业务闭环。发布一个“影视条目”上传封面图回到列表页确认新条目出现进入该条目创建帖子写标题正文然后在帖子下回复一条切换到管理端删除该帖子回到前台确认列表消失。每一步之间用简单的中文旁白串联不需要念代码。第三段约 2 分钟打开数据库客户端。执行SELECT * FROM movie ORDER BY id DESC LIMIT 5和SELECT COUNT(*) FROM post展示数据随操作变化。再打开target目录或mvn package后的 jar 包演示java -jar运行方式证明打包产物可用。录制时要避免的声音和环境问题不要用机械键盘不要用手机外放伴奏不要在旁白里念出数据库密码。输出视频文件名改成讲解视频.mp4放进压缩包的05-讲解视频目录中与论文封面上的日期保持一致——这种细节正是“论文答辩PPT源代码数据库讲解视频”五份材料形成同一证据链的关键。最后把校验步骤回放到命令里自动完成交给压缩包的人也不会在二次部署时卡在配置上。本文还有配套的精品资源点击获取
返回列表