java - JSR-303 自定义验证器中未自动装配依赖项
问题描述
我有一个包含 User 类的 Spring Boot 应用程序 - 所有字段都有标准的 JSR-303 注释(@NotNull、@Size 等)并且验证工作正常。
但是,当我向用户添加自定义验证时,我无法将依赖项注入自定义验证器:
@Component
public class UniqueUsernameValidator implements
ConstraintValidator<UniqueUsername, String> {
@Autowired
private UserRepository userRepository;
@Override
public boolean isValid(String username, ConstraintValidatorContext context) {
// implements logic
}
@UniqueUsername 注释声明为:
@Documented
@Retention(RUNTIME)
@Target({FIELD, ANNOTATION_TYPE, PARAMETER})
@Constraint(validatedBy = UniqueUsernameValidator.class)
@interface UniqueUsername {
String message() default "{com.domain.user.nonUniqueUsername}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
注释字段:
@NotBlank
@Size(min = 2, max = 30)
@UniqueUsername
private String username;
以及验证器的用法:
@Service
public final class UserService {
private final UserRepository userRepository;
private final Validator validator;
public UserService(UserRepository userRepository, Validator validator)
{
this.userRepository = userRepository;
this.validator = validator;
}
public void createUser(User user) {
Set<ConstraintViolation<User>> validate = validator.validate(user);
// logic...
}
}
问题是 UserRepository 没有在 UniqueUsernameValidator 中自动装配。字段始终为空。
我正在使用 LocalValidatorFactoryBean。
有谁知道为什么自动装配不起作用?
@Controller
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping("/user/new")
public String createUser(@ModelAttribute("newUser") User newUser, BindingResult bindingResult,
Model model) {
userService.createUser(newUser);
// omitted
}
解决方案
需要在User前面的public String createUser(@ModelAttribute("newUser") User newUser)的实体类前面加上@Valid注解。
@RequestBody @Valid User user
推荐阅读
- android - 如何将 Jetpack Compose 中的子项传递给自定义可组合项?
- php - 从 WooCommerce 相关产品自定义 WP 查询中删除缺货产品
- mysql - MySQL 触发器可能会静默失败吗?
- javascript - Neovis.js 的只读权限
- azure - Azure Key Vault Service 用于存储凭据
- gpu - clinfo 未检测到英特尔 GPU
- c# - 列表比较和替换匹配条件linq C#
- swift - Swift - 命名函数类型参数
- sql - ms 访问,需要获取具有不同列的所有行
- c++ - 为什么调用 `lower_bound` 函数不需要`std` 前缀?