# 2025SpringBoot **Repository Path**: xiaofei90/2025-spring-boot ## Basic Information - **Project Name**: 2025SpringBoot - **Description**: 2025年上半年,讲解SpringBoot的项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-27 - **Last Updated**: 2025-05-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring Boot 基础项目-V0 这是一个基于 Spring Boot 的基础项目,用于演示 Spring Boot 的基本功能和使用方法。 ## 技术栈 - Spring Boot 2.2.5 - Spring Data JPA - MySQL 数据库 - Thymeleaf 模板引擎 - Maven 构建工具 ## 项目功能 - 用户注册功能 - 管理员后台管理 - 用户信息管理 ## 环境要求 - JDK 1.8 或以上版本 - MySQL 8.0 或以上版本 - Maven 3.6 或以上版本 ## 数据库配置 项目使用 MySQL 数据库,默认配置如下: - 数据库名:springboot - 用户名:root - 密码:123456 - 端口:3306 如果需要修改数据库配置,请编辑 `src/main/resources/application.properties` 文件。 ## 项目部署 1. 克隆项目到本地 ```bash git clone [项目地址] ``` 2. 创建数据库 ```sql CREATE DATABASE springboot CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` 3. 修改数据库配置(如果需要) 编辑 `src/main/resources/application.properties` 文件,修改数据库连接信息。 4. 编译项目 ```bash mvn clean package ``` 5. 运行项目 ```bash mvn spring-boot:run ``` 项目启动后,可以通过以下地址访问: - 首页:http://localhost:8080 - 注册页面:http://localhost:8080/register - 管理员页面:http://localhost:8080/admin ## 使用说明 ### 用户注册 1. 访问 http://localhost:8080/register 2. 填写用户信息 3. 点击注册按钮提交 ### 管理员功能 1. 访问 http://localhost:8080/admin 2. 可以查看所有注册用户 3. 可以添加新用户 4. 可以管理现有用户 ## 项目结构 ``` src/ ├── main/ │ ├── java/ │ │ └── com/example/demo/ │ │ ├── controller/ # 控制器层 │ │ ├── model/ # 数据模型 │ │ ├── repository/ # 数据访问层 │ │ ├── service/ # 业务逻辑层 │ │ └── DemoApplication.java │ └── resources/ │ ├── static/ # 静态资源 │ ├── templates/ # 模板文件 │ └── application.properties ``` ## 注意事项 1. 首次运行时会自动创建数据库表结构 2. 开发环境下模板缓存已关闭,修改模板文件后无需重启 3. 生产环境部署时,请修改数据库密码等敏感信息 4. 建议在生产环境中开启模板缓存 ## 常见问题 1. 如果遇到数据库连接问题,请检查: - MySQL 服务是否启动 - 数据库配置是否正确 - 数据库用户权限是否足够 2. 如果遇到编译问题,请检查: - JDK 版本是否符合要求 - Maven 配置是否正确 - 网络连接是否正常(用于下载依赖) ## 版本控制 项目使用 Git 进行版本控制,目前已经同步到以下仓库: - Gitee: https://gitee.com/xiaofei90/2025-spring-boot.git - GitHub: https://github.com/fly199004/2025SpringBoot.git ### Git 操作说明 1. 初始化仓库 ```bash git init ``` 2. 添加文件到暂存区 ```bash git add . ``` 3. 提交更改 ```bash git commit -m "提交说明" ``` 4. 添加远程仓库 ```bash # 添加 Gitee 仓库 git remote add gitee https://gitee.com/xiaofei90/2025-spring-boot.git # 添加 GitHub 仓库 git remote add github https://github.com/fly199004/2025SpringBoot.git ``` 5. 推送到远程仓库 ```bash # 推送到 Gitee git push -u gitee main # 推送到 GitHub git push -u github main ``` ## 目前存在的问题 1. 没有网页缓存功能 2. 账号密码没有安全机制 3. 没有任务管理 4. 如何打包部署 ## V1版本,添加Redis缓存功能 ### Redis缓存功能实现步骤 1. 添加Redis依赖到pom.xml ```xml org.springframework.boot spring-boot-starter-data-redis ``` 2. 配置Redis连接信息(application.properties) ```properties # Redis配置 spring.redis.host=localhost spring.redis.port=6379 spring.redis.password= spring.redis.database=0 # 缓存配置 spring.cache.type=redis spring.cache.redis.time-to-live=600000 spring.cache.redis.cache-null-values=true ``` 3. 在主应用类中添加缓存注解 ```java @SpringBootApplication @EnableCaching public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` 4. 在Service层添加缓存注解 ```java @Service public class UserService { @Autowired private UserRepository userRepository; @Cacheable(value = "users", key = "'allUsers'") public List getAllUsers() { return userRepository.findAll(); } @CacheEvict(value = "users", allEntries = true) public User saveUser(User user) { return userRepository.save(user); } } ``` 5. 在Controller层添加缓存注解 ```java @Controller public class UserController { @GetMapping("/admin") public String showAdminPage(Model model) { model.addAttribute("users", userService.getAllUsers()); return "admin"; } @PostMapping("/register") @CacheEvict(value = "users", allEntries = true) public String registerUser(User user) { userService.saveUser(user); return "redirect:/register?success"; } } ``` 6. 修改实体类实现序列化接口 ```java @Entity public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; // ... getters and setters } ``` ### 常见问题及解决方案 1. 序列化问题 - 错误信息:`java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type` - 解决方案:让实体类实现 `Serializable` 接口 - 原因:Redis 在存储对象时需要将对象序列化,因此实体类必须实现 `Serializable` 接口 2. 缓存键问题 - 错误信息:`Null key returned for cache operation` - 解决方案:在 `@Cacheable` 注解中指定缓存键 - 示例:`@Cacheable(value = "users", key = "'allUsers'")` ### Redis缓存功能说明 1. 缓存策略: - 使用 `@Cacheable` 注解缓存查询结果 - 使用 `@CacheEvict` 注解在数据更新时清除缓存 - 缓存过期时间设置为10分钟(600000毫秒) 2. 缓存效果: - 首次访问管理员页面时会从数据库加载数据并缓存 - 后续访问会直接从Redis缓存中获取数据 - 当添加新用户或注册新用户时,缓存会被清除 - 下次访问时会重新从数据库加载最新数据 3. 性能优化: - 减少数据库查询次数 - 提高页面响应速度 - 降低服务器负载 ### 注意事项 1. 确保Redis服务器已启动并可以访问 2. 生产环境中建议设置Redis密码 3. 根据实际需求调整缓存过期时间 4. 监控Redis内存使用情况,避免内存溢出 5. 所有需要缓存的实体类必须实现 `Serializable` 接口 6. 缓存键的命名要清晰明确,避免冲突 ## V2版本,添加登录功能 ### 修改说明 1. User 实体类修改 - 添加了完整的 getter 和 setter 方法 - 实现了 Serializable 接口以支持 Redis 缓存 - 原因:为了支持对象序列化和反序列化,确保 Redis 缓存正常工作 2. UserRepository 接口修改 - 添加了 `findByUsername` 方法用于检查用户名是否已存在 - 添加了 `findByUsernameAndPassword` 方法用于登录验证 - 原因:支持用户注册时的用户名查重和登录时的身份验证 3. UserService 类修改 - 添加了用户名查重逻辑,防止重复注册 - 优化了缓存策略,使用 `@Cacheable` 和 `@CacheEvict` 注解 - 添加了登录验证方法 - 原因: - 确保用户名的唯一性 - 提高系统性能,减少数据库访问 - 支持用户登录验证 4. UserController 类修改 - 添加了登录相关的路由和方法 - 添加了错误处理和用户反馈 - 优化了注册流程,支持错误信息显示 - 添加了管理员功能(添加/删除用户) - 原因: - 实现完整的用户认证流程 - 提供更好的用户体验 - 支持管理员对用户的管理 5. 页面模板修改 - 登录页面(login.html): - 添加了错误消息显示 - 保留了用户名输入 - 优化了页面布局 - 原因:提供更好的用户体验和错误反馈 - 注册页面(register.html): - 添加了错误和成功消息显示 - 保留了用户输入数据 - 优化了表单布局 - 原因:提供更好的用户体验和操作反馈 - 管理员页面(admin.html): - 添加了错误消息显示 - 优化了用户列表显示 - 添加了删除用户功能 - 原因:提供更好的管理体验和操作反馈 ### 登录功能实现步骤 1. 修改 User 实体类 ```java @Entity public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } ``` 2. 修改 UserRepository 接口 ```java public interface UserRepository extends JpaRepository { User findByUsername(String username); User findByUsernameAndPassword(String username, String password); } ``` 3. 修改 UserService 类 ```java @Service public class UserService { @Autowired private UserRepository userRepository; @Cacheable(value = "users", key = "'allUsers'") public List getAllUsers() { return userRepository.findAll(); } @CacheEvict(value = "users", allEntries = true) public User saveUser(User user) { User existingUser = userRepository.findByUsername(user.getUsername()); if (existingUser != null) { throw new RuntimeException("用户名已存在"); } return userRepository.save(user); } public User findByUsernameAndPassword(String username, String password) { return userRepository.findByUsernameAndPassword(username, password); } } ``` 4. 修改 UserController 类 ```java @Controller public class UserController { @Autowired private UserService userService; @GetMapping("/") public String index() { return "redirect:/login"; } @GetMapping("/login") public String showLoginForm() { return "login"; } @PostMapping("/login") public String login(@RequestParam String username, @RequestParam String password, Model model) { User user = userService.findByUsernameAndPassword(username, password); if (user != null) { return "redirect:/admin"; } else { model.addAttribute("error", "用户名或密码错误"); return "login"; } } @GetMapping("/register") public String showRegisterForm(Model model) { model.addAttribute("user", new User()); return "register"; } @PostMapping("/register") public String registerUser(@ModelAttribute User user, Model model) { try { userService.saveUser(user); return "redirect:/register?success"; } catch (Exception e) { model.addAttribute("error", e.getMessage()); model.addAttribute("user", user); return "register"; } } @GetMapping("/admin") public String showAdminPage(Model model) { model.addAttribute("users", userService.getAllUsers()); model.addAttribute("newUser", new User()); return "admin"; } @PostMapping("/admin/addUser") public String addUserFromAdmin(@ModelAttribute User user, Model model) { try { userService.saveUser(user); return "redirect:/admin"; } catch (Exception e) { model.addAttribute("error", e.getMessage()); model.addAttribute("users", userService.getAllUsers()); model.addAttribute("newUser", user); return "admin"; } } @GetMapping("/admin/delete/{id}") public String deleteUser(@PathVariable Long id) { userService.deleteUser(id); return "redirect:/admin"; } } ``` 5. 创建登录页面(login.html) ```html 登录

用户登录

``` 6. 修改注册页面(register.html) ```html 注册

用户注册

``` 7. 修改管理员页面(admin.html) ```html 管理员页面

用户管理

ID 用户名 操作
删除
``` ### 登录功能说明 1. 功能特点: - 支持用户名和密码登录 - 登录失败显示错误信息 - 登录成功跳转到管理员页面 - 提供注册入口 - 支持用户注册 - 支持管理员添加和删除用户 2. 安全特性: - 密码在传输过程中使用表单提交 - 登录失败不显示具体错误原因 - 支持基本的输入验证 - 用户名唯一性检查 3. 用户体验: - 响应式设计,适配不同设备 - 清晰的错误提示 - 简洁的界面布局 - 保留用户输入数据 - 显示操作成功消息 ### 注意事项 1. 登录功能目前使用简单的用户名密码验证 2. 建议在生产环境中添加: - 密码加密存储 - 登录失败次数限制 - 验证码功能 - Session管理 - 记住我功能 ### 后续优化计划 1. 添加密码加密功能 2. 实现记住我功能 3. 添加验证码功能 4. 实现登录失败次数限制 5. 添加Session管理 6. 实现权限控制 ## 版本说明 ### V2版本 - 添加了Redis缓存支持 - 优化了用户注册和登录流程 - 添加了错误处理和用户反馈 - 改进了页面UI和用户体验 - 添加了错误消息显示功能 - 在注册页面显示成功消息 - 保留用户输入数据 - 优化了页面布局和样式 - 添加了删除用户功能 - 支持管理员功能 - 查看所有用户 - 添加新用户 - 删除用户 - 添加了用户会话管理 - 实现了基本的权限控制 ### V1版本 - 添加redis缓存支持