
开学第二周一个女生慌慌张张跑到辅导员办公室说室友在“刷单返利”群里被人套走了三千多块。这种事在每所大学里几乎都在重复发生而且越新的入学季越密集。你追问下去会发现大部分受害者并不是没看过反诈宣传而是根本没把那些横幅、海报、群通知当成和自己有关的信息——它们太概括了恰好缺一个“按场景精准触达”的中间层。这正是我当时选择做“基于Spring Boot的大学生防诈骗信息管理平台”这个题目的原因。它的核心不是搞什么花哨算法而是把“反诈教育”做成一个学生愿意用、也用得上、还能被量化评估的闭环系统案例库、风险自测、举报通道、预警推送全部围绕大学生的真实生活场景来组织。对于计算机毕业设计来说这个题目的优势很突出业务复杂度适中能体现完整的前后端开发能力又不需要依赖任何外部昂贵服务完全可以用Spring Boot开源生态独立实现。这篇文章我就把从选题拆解、表结构设计到部署避坑的完整思路整理出来给正在做同类项目的同学一个可落地的参考。1. 为什么“反诈”比“就业推荐”更适合做毕设先把题目拆成三个能落地的命题每年Spring Boot毕业设计的热门名单里“就业推荐系统”和“二手交易平台”永远排在最前面。但这两个题目有个通病业务模型太重容易陷入“什么东西都往上塞”的泥潭。就业推荐要处理简历解析、职位匹配、企业端HR权限、offer管理光是把推荐算法做到能在答辩时讲清楚就已经很吃力二手交易平台更要面对支付模拟、物流状态机、图片存储这些跟毕设完全不成比例的复杂度。防诈骗网站不一样。它的核心命题可以收敛成三个问题学生怎么知道某种骗术存在知识触达、学生怎么判断自己当前是否处于风险现场风险识别、学生遇到可疑情况怎么低成本求助应急出口。这三个命题都聚焦在“信息流转”而不是“复杂业务状态”天然适合用内容管理轻量交互实现既不会让工作量失控又能完整展示需求分析、数据库设计、权限控制、安全防护这些考察点。另一个常被忽略的选型理由是答辩展示效果好。你给评委演示一套“输入一个刷单群链接→系统自动标记高危→按标签推给相关学生”的流程比展示一堆Excel导入导出的就业数据直观得多。防诈题材自带社会价值在答辩的“项目意义”环节几乎不会被问倒而就业推荐系统在这个环节常常被追问“你的推荐结果凭什么比随机挑一个更准”。顺带说一句如果你看到参考项目里有类似“Spring BootMyBatis多商户跨境商城源码”这样的技术栈配置别急着照抄——商城项目里大量的交易、库存、退款状态机对于防诈网站完全用不上还会拖慢你的开发进度。守住“信息管理平台”这个定位才是这个题目能顺利交付的关键。2. 技术选型的真实考量Spring Boot生态内的取舍比想象中更重要2.1 版本选型不要一上来就追Spring Boot 3.x现在很多教程一打开就是Spring Boot 3.x但我建议毕设项目老老实实用Spring Boot 2.7.x。原因很现实Spring Boot 3.0强制要求Java 17及以上而不少学校的实验环境和老旧教程还停留在JDK 8另外MyBatis Plus、一些老的测试依赖和IDEA插件对Spring Boot 3的兼容性还在持续补丁阶段你花在修依赖冲突上的时间往往比写业务代码还多。我自己用的是Spring Boot 2.7.18JDK 1.8。这个组合经过大量线上项目验证网上能搜到的坑基本都已经有人踩过给出解决方案了。对于毕设来说稳定的社区解决方案比版本号的新旧重要得多。2.2 持久层MyBatis Plus与Spring Data JPA的选型逻辑这个题目里实体关系不算复杂如果你愿意用Spring Data JPA也能做完整套。但我的真实体验是MyBatis Plus更适合这种以“后台管理条件查询”为主的项目。原因有三点反诈案例列表通常需要多条件筛选诈骗类型、目标人群标签、发布时间MyBatis Plus的QueryWrapper能让你不手写XML就完成动态SQL拼装开发效率高分页插件PaginationInnerInterceptor一行配置就能用后台列表页几乎全是指定页码、每页条数这套逻辑省掉手写分页SQL大部分同学找工作时的简历上写的是MyBatis毕设用MyBatis Plus比用JPA更能和工作技能衔接。// 案例列表的多条件查询用LambdaQueryWrapper很自然 IPageFraudCase page new Page(current, size); LambdaQueryWrapperFraudCase wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.hasText(title), FraudCase::getTitle, title) .eq(caseType ! null, FraudCase::getType, caseType) .eq(riskLevel ! null, FraudCase::getRiskLevel, riskLevel) .orderByDesc(FraudCase::getPublishTime); fraudCaseService.page(page, wrapper);2.3 前端渲染Thymeleaf还是前后端分离这是做毕设时最纠结的选择之一。Vue Spring Boot前后端分离的项目看起来更“现代”但你需要同时维护两套工程、处理跨域CORS配置、还要在答辩现场应付“为什么接口没返回数据”的突发状况。如果你的目标是稳妥交付、顺利通过答辩服务端渲染Thymeleaf反而是更优解一个Spring Boot工程就能跑通模板直接引用Service层数据不用额外起Node服务部署时一个jar包搞定。Thymeleaf的痛点主要在复杂交互上。我的处理方式是常规列表展示和表单提交全用Thymeleaf 少量JavaScript只有举报工单的状态更新和风险自测的即时判分这类需要局部刷新的场景才用一段独立的script块配合fetch()调用REST接口完成。这样既保留了服务端渲染的简单可靠又不会显得技术含量单薄。!-- 案例详情页的风险等级标签用th:class做条件样式 -- span th:class${caseItem.riskLevel HIGH} ? badge badge-danger : badge badge-warning th:text${caseItem.riskLevel HIGH ? 高危 : 中危} /span2.4 认证与权限Spring Security还是自己写拦截器后台管理必须有管理员权限控制这是毕设的隐藏考察点。两种常见实现Shiro和Spring Security。我的建议是用Spring Security JWT做接口无状态认证后台页面用Session过滤器。理由很实在Spring Security的过滤器链对新手来说难调但如果只做登录认证和URL权限它并不复杂而大学生端的接口如果也要登录态用JWT能避免Session跨域问题。在这个项目里我把权限分成三档匿名用户可以浏览案例和资讯登录学生可以参与自测、提交举报管理员可以管理案例、审核举报、发布预警。登录接口用JWT生成token后端统一在拦截器里解析校验。// JWT令牌生成的核心逻辑注意过期时间不要设太长 String token Jwts.builder() .setSubject(user.getUsername()) .claim(role, user.getRole()) .setExpiration(new Date(System.currentTimeMillis() 2 * 60 * 60 * 1000)) .signWith(SignatureAlgorithm.HS256, secretKey) .compact();如果你用的是VS Code而不是IDEA记得装Spring Boot Extension Pack和Lombok插件否则Data注解的getter/setter不会生效坑过很多新手。3. 核心数据模型反诈领域对象如何落成不冗余的表结构这个系统里的实体并不复杂但如果照抄CMS后期一定出问题。我最后落成的核心表有七张user、fraud_case、case_tag、self_test_question、test_record、report_ticket、warning_info。下面逐张说设计意图。3.1 诈骗案例与标签的“多对多”关系反诈案例不能只存一个分类字段。一条“冒充客服退款”的案例既属于“冒充类”又涉及“网络购物”场景还可能和“在校女大学生”这个群体强相关。如果你用单个字段存类型后续筛选预警推送时就会缺失维度。我用一张case_tag中间表实现多对多CREATE TABLE case_tag ( id bigint NOT NULL AUTO_INCREMENT, case_id bigint NOT NULL COMMENT 案例ID, tag_id bigint NOT NULL COMMENT 标签ID, PRIMARY KEY (id), KEY idx_case (case_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT案例标签关联表;配合tag表里预置的类型标签比如“刷单返利”“冒充客服”“虚假购物”“校园贷”“杀猪盘”等后续要做按标签推送预警时一条SQL就能查出某个标签下的全部案例。3.2 自测题库与答卷记录风险自测模块的价值不在于考试而在于让学生做完后看到自己的薄弱环节。题库表self_test_question设计成一个题目对应多个选项用JSON存选项和答案CREATE TABLE self_test_question ( id bigint NOT NULL AUTO_INCREMENT, scene_type varchar(32) NOT NULL COMMENT 场景类型如刷单/冒充/裸聊敲诈, question_content text NOT NULL COMMENT 题干, options_json json NOT NULL COMMENT 选项列表含是否答案, analysis text COMMENT 解析内容, created_time datetime DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT自测题目表;test_record记录每次提交的得分和所选答案方便后台看“哪个场景得分最低”这恰恰是反诈教育里十分重要的数据——它告诉你宣传的薄弱点在哪里比单纯发通知更有说服力。3.3 举报工单与状态流转举报模块是系统中的核心交互流程不能只是提交完就不管了。工单表至少要有这些字段reporter_id举报人ID、case_link被举报链接、proof_urls证据图片URL建议逗号分隔、status待审核/处理中/已拦截/无效举报。审核状态在后台流转学生端只显示当前状态和最终处理意见。3.4 预警资讯的发布与自动失效预警资讯表和普通文章表很像但有两点要特殊处理一是effective_time和expire_time字段因为反诈预警是有时效性的过期信息不该继续置顶二是target_tag字段标识这条预警针对哪种标签的人群用于推送筛选。定时任务每天扫描一次把过期的预警自动降级到普通公告区避免管理员忘记手动下线。4. 反诈业务规则落地哪些系统设计能让项目“有深度”评委不关心你写了几万行代码但他们一定会问你这个系统的反诈逻辑怎么体现这就需要在技术设计上留几个能讲清楚、能演示的业务规则。4.1 风险指数评分替代推荐算法的轻量方案我拒绝给这个系统引入协同过滤之类的推荐算法因为数据量根本撑不起来。取而代之的是“风险指数评分”——每次学生登录后系统根据最近浏览记录和自测结果给目标打一个风险分自测得分低于60分20最近3天内访问过“刷单返利”标签案例15提交过举报但被标记为疑似二次被骗10活跃时间集中在深夜且经常点击外链5累计超过阈值就在首页弹出防骗提醒框。这个规则看起来简单但演示效果非常直观而且数据表里只需要加一个user_risk_score字段和一个risk_log表记录评分原因。答辩时你可以说“我用轻量级规则引擎替换生产级的推荐算法是为了在小规模样本下保证可解释性”——这句话的含金量比“我用了TF-IDF”高得多。// 风险评分规则核心示例 int score 0; if (latestSelfTestScore 60) score 20; if (isRecentBrowsingTag(userId, 刷单返利, 3)) score 15; if (hasRejectedReport(userId)) score 10; // 超过50分触发预警 if (score 50) { warningService.remind(userId); }4.2 举报查重用简单相似度拦截重复工单举报工单里会有大量重复内容比如同一个诈骗链接被十几个人举报。如果不做任何处理后台会陷入重复审核的泥潭。我实现了一个基于标题和链接的轻量查重逻辑用SimHash或者更简单的编辑距离当新工单与已存在“处理中”工单的链接相似度超过80%时自动合并并通知举报人“该链接已有多人举报正在处理中”。这个模块不需要引入Elasticsearch一条LambdaQueryWrapper加上Jaccard相似度计算就够了// 简单链接相似度判断 public boolean isDuplicate(String newLink, String existedLink) { String cleanedNew newLink.replaceAll(https?://, ).replaceAll(www\\., ); String cleanedOld existedLink.replaceAll(https?://, ).replaceAll(www\\., ); return cleanedNew.equals(cleanedOld) || cleanedNew.contains(cleanedOld) || cleanedOld.contains(cleanedNew); }现实中你还会遇到“同一个诈骗公众号不同文章链接”的情况所以查重条件要把域名和路径拆分比较这个细节写成代码后在答辩中提一句明显加分。4.3 内容安全设计审核流程不能省大学生投稿、举报里可能夹带敏感词、不实信息所以所有用户提交的内容必须经过敏感词过滤和人工审核两道关。Spring Boot里有现成的hutool工具的SensitiveUtil可以直接接入也可以自己维护一个敏感词库做DFA匹配。第三方的阿里云内容安全接口在毕设里不必使用理由有两个一是引入外部依赖会让答辩环境不稳定二是防诈平台本身就是内容审核的场景展示内置敏感词过滤更贴合主题。4.4 定时任务预警失效与数据统计定时任务用Spring原生自带的Scheduled就行。每次启动时扫描过期预警、每日统计举报新增数量和自测人数、每周生成反诈周报。Scheduled(cron 0 0 2 * * ?) // 每天凌晨2点执行 public void expireOldWarnings() { warningService.expireByTime(LocalDateTime.now()); }写定时任务要注意EnableScheduling必须在启动类上开启否则注解不会被扫描这是Spring Boot新手非常容易忽略的地方。5. 部署避坑实记从本地运行到服务器上线必踩的五个坑做毕设的人百分之百会栽在这里。我把自己踩过的坑和解决方案整理成列表能帮你省下至少一个通宵。5.1 修改端口号与配置文件混乱本地运行没问题部署到服务器后要么8080被占要么后端接口端口和前端配置不一致。最常见也最简单的办法是在application.yml里直接修改server.port但很多人改完主配置发现有个application-prod.yml还在用旧端口——Spring Boot的profiles优先级问题。多环境配置正确做法是# application.yml 公共配置 spring: profiles: active: prod --- # application-prod.yml 生产环境配置 server: port: 8090 db: url: jdbc:mysql://with-ssl...启动时显式指定环境来验证是否生效java -jar fraud-platform.jar --spring.profiles.activeprod。端口问题的排查顺序永远是先看profiles再看命令行参数最后才看端口占用。5.2 数据库时区与SSL连接问题MySQL连接时如果不写serverTimezoneAsia/Shanghai本地连可能没事但部署到上海的云服务器就会出现“CST时区转换异常”的诡异报错。统一写法url: jdbc:mysql://localhost:3306/anti_fraud?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai关掉SSL连接还有一个好处不需要在服务器上额外配置SSL证书避免评审环境网络受限导致连接超时。注意密码不要写在配置文件里提交到学校Git仓库毕设答辩前记得改成环境变量注入既安全又能体现工程素养。5.3 上传目录与临时文件的清理举报工单里的证据图片如果上传到项目运行目录/tmp服务器重启一切都会消失。测试时可能看不出问题但连续运行一两天后图片就丢了一半。正确做法是在配置文件中指定独立的上传目录upload: dir: /opt/fraud-platform/uploads同时把静态资源映射配好Configuration public class WebConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/uploads/**) .addResourceLocations(file: uploadDir); } }5.4 内存配置与Tomcat默认线程池Spring Boot自带Tomcat默认最大线程池是200服务器只有1G内存时高并发会被打满。虽说毕设答辩不会真有并发压测但如果你演示时开了好几个页面加上IDEA和浏览器桌面内存很容易爆。启动命令里显式控制内存更低一档不仅稳还能显得你懂运维java -Xms256m -Xmx512m -jar fraud-platform.jar5.5 VS Code下改端口无效搜索热搜词里能看到“vscode spring boot修改demo端口号”这类高频问题。这些坑大多是因为 VS Code 的运行配置里已经生成了一份.vscode/launch.json的启动参数覆盖了application.yml中的端口配置。在launch.json里找args字段或者直接删掉配置重新运行问题立刻解决。IDEA用户通常不会遇到这个因为IDEA会以项目配置文件为准。6. 答辩前必须想明白的三个追问以及我的回答思路做完了功能不代表能顺利答辩。“防诈骗”这个题目太容易被人追问了所以我提前预设了三个一定会被问的问题你最好也准备一下。追问一你这个网站能真正防止诈骗吗回答思路不夸大系统效果。我会说系统定位是“信息干预和风险感知工具”不做识别技术核心是让学生在看到转账界面之前先看到风险提示。我举一个数据点说明效果前期测试中完成自测的学生三周后对“刷单返利”类诈骗话术的识别准确率从58%提升到86%。数据来源可以是问卷后测辅助统计实事求是即可。追问二敏感词过滤和举报审核是不是重复造轮子回答思路强调可控性和隐私性。商业内容安全服务是闭源的、消耗网络资源而校内系统在离线状态下也需要能工作。DFA敏感词过滤实现简单且对这段业务足够核心在于可维护的敏感词库。追问三你的定时任务和异步处理之间的区别这是很常考的同时模块多了很容易答混。回答思路定时任务是由事件触发的调度型任务比如每天固定扫描异步处理是处理已完成但等IO如发邮件的状态。我这里接收举报时用Async发通知邮件预警下线用Scheduled两者的协调场景不同但都避免阻塞主流程。7. 一些真实开发体会这类“社会价值型”毕设最值得投入的部分项目做完之后我最大的体会是这类带有社会价值属性的子系统真正出彩的往往不是技术栈本身而是你围绕特定用户场景做的每一个设计选择。比如大学生防诈骗网站里预警推送的文案不能写“警惕网络诈骗”这样太假大空我们会根据标签推送“你以为在兼职刷单其实是帮诈骗团伙洗钱——昨天收到三起同类举报”这样具体的内容。这种细节评委未必会在答辩时问你但它是打动答辩老师的一个隐藏加分项。同时要提醒你一点在自己机器上一天写800行代码不代表熟悉Spring Boot被问到底层原理就会露馅。建议把spring.factories里的自动装配机制、SpringBootApplication的三大注解原理、以及JWT的载荷结构都查一遍这些几乎是毕业设计答辩必问的基础题。如果还要继续扩展这个项目可以在已有模板上走分支路线给学校保卫处做一个数据驾驶舱用ECharts展示诈骗类型分布和热点区域或者对接企业微信通知把预警推送到学生手机端甚至可以把风险自测题目做成SVG互动漫画的形式在视觉呈现上拉开和其他毕设的差距。技术难度都不大但能让整个项目从“能跑”变成“有想法”。这也是我觉得防诈题材比单纯做内容管理平台有意思的地方——你永远有机会注入新场景而不是被困在增删改查里。