自定义UniqueEmail ConstraintValidator失效,报空指针异常求助
解决方案
问题根源
Bean Validation(JSR-380)的默认校验器实例由ValidatorFactory创建,不受Spring容器管理——哪怕给UniqueEmailValidator加了@Component,Spring也没法为其注入UserService,这就是空指针异常的原因。
修复步骤
1. 调整自定义校验器的依赖注入
确保UniqueEmailValidator类上有@Component,并用@Autowired注入UserService:
@Component public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> { @Autowired private UserService userService; @Override public void initialize(UniqueEmail constraintAnnotation) { // 初始化逻辑(按需添加) } @Override public boolean isValid(String email, ConstraintValidatorContext context) { if (email == null) { return true; // 空值交给@NotNull/@NotEmpty处理 } return !userService.isEmailExist(email); } }
2. 配置Spring接管校验器创建
新增配置类,注册LocalValidatorFactoryBean,让Spring管理校验器生命周期,从而支持依赖注入:
@Configuration public class ValidationConfig { @Bean public LocalValidatorFactoryBean validator() { return new LocalValidatorFactoryBean(); } }
(如果需要自定义校验提示信息,可以额外配置MessageSource,否则上述代码足够)
3. 修正UserRepository方法
JPA中判断邮箱是否存在应该用existsByEmail,而非findByEmail:
public interface UserRepository extends JpaRepository<User, Long> { boolean existsByEmail(String email); }
然后在UserService中封装这个方法:
@Service public class UserService { @Autowired private UserRepository userRepository; public boolean isEmailExist(String email) { return userRepository.existsByEmail(email); } }
4. 保留控制器的校验注解
控制器方法继续使用@Valid或@Validated(后者支持分组校验):
@RestController @RequestMapping("/api") public class UserController { @Autowired private UserService userService; @PostMapping("/addUser") public ResponseEntity<String> addUser(@Valid @RequestBody User user) { userService.save(user); return ResponseEntity.ok("用户添加成功"); } }
5. 移除无效配置
删除application.properties中的spring.jpa.properties.javax.persistence.validation.mode=none,让内置校验和自定义校验同时生效。
验证
启动项目后调用/api/addUser接口:
- 传入已存在的邮箱,会返回400校验错误
- 传入合法新邮箱,能正常完成用户添加
内容的提问来源于stack exchange,提问作者smhylc
相关产品推荐
相关产品推荐

