需完成实体定义、数据持久化、业务逻辑封装、接口暴露和基础安全控制五环节:定义User实体并用@Entity/@Table映射表,主键加@Id/@GeneratedValue,用户名加@Column(unique=true);建UserRepository继承JpaRepository并声明findByUsername方法;UserService中用BCryptPasswordEncoder加密存库、matches校验登录;@RestController暴露/login接口返回标准JSON;启用H2内存数据库并访问/h2-console验证数据。
用Spring Boot快速搭建一个可运行的用户登录系统,需要完成实体定义、数据持久化、业务逻辑封装、接口暴露和基础安全控制五个环节,缺一不可。
在src/main/java下新建com.example.login.entity包,创建User.java文件:
添加@Entity和@Table(name = "sys_user")注解,声明该类为JPA实体并绑定数据库表名;主键字段必须标注@Id和@GeneratedValue(strategy = GenerationType.IDENTITY),否则H2或MySQL插入时会报错;用户名字段建议加@Column(unique = true)约束,避免注册重复账号。
密码字段命名为password而非hashedPassword——因为后续要用BCryptPasswordEncoder加密,原始输入是明文,存库的是密文,字段名保持语义一致更利于维护。
在com.example.login.repository包中新建UserRepository.java:
继承JpaRepository<User, Long>,无需写任何方法体,JPA自动提供save()、findById()、findByUsername()等基础操作;显式声明User findByUsername(String username)方法,这是登录校验时按用户名查用户的最简路径。
【必须确保方法名严格遵循JPA命名规范】:若写成findUserByUsername或getUserByName,JPA无法解析,运行时报Invalid derived query!异常。
第一步:在com.example.login.service包中创建UserService.java,添加@Service注解;
第二步:注入UserRepository和BCryptPasswordEncoder(需在配置类中声明为@Bean);
第三步:注册方法中调用passwordEncoder.encode(rawPassword)对明文密码加密后再存库,绝不允许明文入库;
第四步:登录方法先用userRepository.findByUsername(username)查用户,再用passwordEncoder.matches(inputPassword, user.getPassword())比对——这是唯一安全的校验方式,直接用equals()比较密文字符串会失败,因为BCrypt每次加密结果不同。
方法一:使用@RestController + @PostMapping("/login"),接收@RequestBody LoginRequest对象(含username/password字段),校验通过返回ResponseEntity.ok(Map.of("token", jwtToken));
方法二:若暂不引入JWT,可返回简单结构:return Map.of("success", true, "message", "登录成功", "username", user.getUsername());
注意:不要用String直接拼JSON,Spring Boot默认用Jackson序列化Map,简洁且无转义风险。
1. 在pom.xml中添加com.h2database:h2依赖(scope为runtime);
2. application.properties中配置:spring.datasource.url=jdbc:h2:mem:testdb、spring.h2.console.enabled=true;
3. 启动项目后访问http://localhost:8080/h2-console,填入JDBC URL: jdbc:h2:mem:testdb,点击Connect;
4. 执行SELECT * FROM sys_user;确认注册用户已存入——这一步能立刻验证实体映射、Repository和Service是否连通,比日志排查快5倍。