山东大学软件学院2026项目实训个人博客(二)

张开发
2026/4/19 1:15:17 15 分钟阅读

分享文章

山东大学软件学院2026项目实训个人博客(二)
项目名称基于AI大模型的智能考研社区撰写日期2026年4月18日本周我主要完成了项目基础环境的进一步搭建和Redis、RabbitMQ配置的完善优化当前注册功能、登录功能、错题本CRUD功能并进行Swagger测试。一、基础环境搭建从git仓获取我负责的后端分支develop-backend后我着手进行基础环境的搭建和本地化配置。1Redis配置类MessageServiceImpl 通过RequiredArgsConstructor 注入了 RedisTemplateString, Object。Spring Boot 虽然引入了 spring-boot-starter-data-redis 依赖但默认只自动配置了 RedisTemplateObject, Object不会自动配置 RedisTemplateString, Object因此 Spring 无法找到匹配的 Bean。因此我创建 RedisConfig 配置类定义 RedisTemplateString, Object Bean// 使用 String 序列化 Key template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); // 使用 JSON 序列化 Value template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());2RabbitMQ安装Erlang和rabbitmq。在RabbitMQ Command Prompt (sbin dir)命令行中启动rabbitmq-plugins enable rabbitmq_management登录进入RabbitMQ仪表盘后在顶部菜单点击 Queues。在列表中找到 chat-queue或者是报错日志里提到的队列名。点击该队列进入详情页。向下滚动找到 Purge 按钮。点击 Purge messages 确认清空Purge目的是清除队列中堆积的异常消息、无效消息或消费失败的死信避免旧消息持续引发程序报错使队列恢复正常可用状态保证新消息能够正常生产与消费。进一步完善RabbitMQConsumerService.java增加 Channel 和 deliveryTag 参数防止无法手动确认消息导致脏消息一直重试可以调用 basicAck /basicNack 控制消息确认增加 startsWith ({) 校验防止Fastjson 收到 error 等文本直接崩溃提前拦截非 JSON 消息避免解析异常增加 basicNack (deliveryTag, false, false)防止错误消息无限重试刷屏报错拒绝消息且不再入队false, false彻底丢弃。3创建本地MySQL数据库并修改配置文件在 Sprint 1 初期进行环境联调时发现本地开发机无法稳定连接远程云服务器IP: 47.104.236.72的 MySQL 服务。因此将开发阶段的数据源切换至本地。在开发机部署 MySQL 8.0 服务并通过 Navicat/DBeaver 等可视化工具进行数据库管理。编写完整的 DDL 脚本在本地创建 studynote_localdev 数据库并初始化 user用户表、notebook错题本表等 6 张核心业务表。利用 Spring Boot 的 Profile 机制在 application-dev.yml 中独立配置本地数据源jdbc:mysql://localhost:3306/studynote_localdev避免污染远程测试数据解决 JDBC 驱动字符集兼容性问题配置 characterEncodingUTF-8 。二、完善现有功能当前一部分实体类、数据库层、DTO/VO类、Impl 核心逻辑和Controller暴露借口存在缺少注解、代码不简洁、安全性不高等问题需要进一步完善。1完善User实体类和UserMapper数据访问层给User实体类的添加 Swagger 注解(Schema)使代码更易读指向更明确。同时删除了原来的 IdType.AUTO改为 IdType.ASSIGN_ID使之与配置文件保持一致。同样给UserMapper.java数据访问层添加注释说明各个接口用途。2完善登录功能在初始的登录功能中后端的LoginVO和UserController会将password明文返回给前端这在功能上是没必要的反而会影响安全性。登录流程分为两个阶段阶段 1验证身份后端内部完成首先用户输入用户名密码后端查询数据库找到该用户后对比密码是否正确如果正确则验证通过 。这个阶段是在后端内部完成的前端只需要发送用户名和密码不需要接收密码回来。阶段 2返回登录结果给前端后端验证通过后生成JWT Token包含 userId用于后续请求的身份凭证并将用户 ID、用户名、头像、Token返回给前端。前端保存 Token跳转到首页。可以发现在登录全流程中后端不需要把密码返回给前端。并且这种行为存在很大的安全隐患。因此要移除 LoginVO 中的 password 字段同时修改 UserController不再返回 password。此外我发现UserController的登录缺少验证没有检查用户名是否为空、没有检查密码是否为空、没有检查用户名长度限制、没有检查密码强度。这会导致当用户提交空的用户名或密码会引起不必要的数据库查询可能被恶意利用进行 SQL 注入攻击虽然 MyBatis-Plus 有防护但最好还是验证因此在 LoginDTO 中添加验证注解同时在 UserController 中添加 Valid 注解启用验证。Data Schema(description 用户登录信息) public class LoginDTO { NotBlank(message 用户名不能为空) Size(min 1, max 20, message 用户名长度必须在1-20个字符之间) Schema(description 用户名) private String name; NotBlank(message 密码不能为空) Size(min 6, max 20, message 密码长度必须在6-20个字符之间) Schema(description 密码) private String password; }3修改JwtUtil中Secret key直接在文件里的硬编码在当前版本JwtUtil中的Secret key是直接在文件里硬编码的这导致代码安全性差 代码提交到 Git 后所有人都能看到 Secret Key不灵活如果想修改过期时间需要重新编译代码以及开发、测试、生产环境无法区分。public static String signKey Journey;public static Long expire 432000000L;public static String signName Authorization;因此将JWT 配置移到 application-dev.yml而JwtUtil需要从配置中获取相关内容。private static String signKey; Value(${jwt.sign-key}) public void setSignKey(String key) { signKey key; } //expire和signName同理在application-dev.yml添加配置jwt: sign-key: Journey expire: 432000000 sign-name: Authorization这样做的好处是配置统一管理在 yml 文件中不同环境可以使用不同的配置dev/test/prod修改配置不需要重新编译代码符合 Spring Boot 的最佳实践。三、注册登录功能和错题本CRUD功能的Swagger测试运行StudynoteApplication控制台输出项目后端启动成功可以进行Swagger测试。1注册和登录功能测试在Swagger测试页面里找到用户管理栏目的user/register和user/login测试块点击Try it out输入测试数据点击Execute{ name: test041801, password: 123456 }HTTP状态码为200返回值均正常注册和登录功能测试成功。2错题本CRUD功能测试a.添加错题本——/notebook/add测试数据{ id: 0, name: 错题本test_0418_1, brief: 这是一个错题本添加测试_0418_1 }b.获取错题本列表——/notebook/listc.获取错题本详情——/notebook/detaild.更新错题本基本信息——/notebook/update测试数据{ id: 1, name: 错题本test0418_1_已更改, brief: 这是一个错题本更新测试_0418_1 }e.删除错题本——/notebook/delete测试数据{ id: 1 }错题本CRUD功能Swagger测试全部圆满完成。本周感悟在本次后端开发的第一阶段我最大的收获是增强了排查和调试错误、优化代码和功能、进行代码测试的能力。项目初期我没有设置好远程数据库配置不过最终通过在本地搭建 MySQL 并配合可视化工具完成建表解决了问题。随着用户登录与错题本核心功能的跑通我开始重新检查代码的质量与安全性。我意识到后端接口不能仅仅满足“功能可用”更要考虑数据边界与隐私保护。因此我主动移除了登录响应中的密码字段并将 JWT 密钥从代码中剥离至配置文件。这些改动加深了我对防御性编程、后端安全性的理解也学会了如何通过配置外置来兼顾系统的安全性与灵活性。在团队协作中我对 Git 分支管理与提交规范有了更直观的认识。清晰的版本记录不仅是工作量的证明更是多人并行开发时保持代码秩序的重要保障。回顾这一阶段的开发从环境搭建到Swagger测试成功每一行代码的落地都让我对后端架构有了更立体的认知。后端开发不仅仅是实现业务逻辑更是构建稳定、安全、易维护的服务体系。接下来的开发中我将带着这份学习的热情和开发的严谨继续推进本次创新项目实践的后续功能开发努力为整个平台打下坚实的后端基础。

更多文章