java - 基于 Spring 自定义条件的验证
问题描述
我想在 spring 验证器中创建基于条件的验证。我有一个UserDTO类,其中有两个带@Valid
注释的 DTO 类。
如果我通过isPrimary true
那么它应该只验证primaryDTO bean 并忽略secendoryDTO验证。
public class UserDTO {
@Valid
private PrimaryDTO primaryDTO;
@Valid
private SecendoryDTO secendoryDTO;
private boolean isPrimary;
}
public class PrimaryDTO {
@NotEmpty(message = "Please enter email.")
@Email(message = "Please enter a valid email.")
private String email;
}
public class SecendoryDTO {
@NotEmpty(message = "Please enter phone.")
private String phone;
}
请指导。
谢谢
解决方案
如果您的验证依赖于多个字段(例如isPrimary
,primaryDTO
或者secondaryDTO
),那么唯一的解决方案是在类级别()上编写一个自定义验证器UserDTO
,它将实现条件验证本身。
例如,创建一个注解:
@Documented
@Retention(RUNTIME)
@Target({ANNOTATION_TYPE, TYPE})
@Constraint(validatedBy = SecondaryValidator.class)
public @interface ValidSecondary {
String message() default "Invalid secondary";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
并创建一个验证器,仅在issecondaryDTO
时验证该字段:isPrimary()
false
@Component
public class SecondaryValidator implements ConstraintValidator<ValidSecondary, UserDTO> {
private Validator validator;
public SecondaryValidator(Validator validator) {
this.validator = validator;
}
@Override
public boolean isValid(UserDTO userDTO, ConstraintValidatorContext constraintValidatorContext) {
if (userDTO.isPrimary()) {
return true;
} else {
return validator.validate(userDTO.getSecondaryDTO()).isEmpty();
}
}
}
之后,您可以@Valid
从secondaryDTO
字段中删除注释并将@ValidSecondary
注释添加到您的顶部UserDTO
:
@ValidSecondary // Add this
public class UserDTO {
@Valid
private PrimaryDTO primaryDTO;
private SecondaryDTO secondaryDTO; // No more @Valid
private boolean primary;
}
但是,在这种情况下,您将丢失 中的任何约束违规消息SecondaryDTO
,如果您想要某种传递机制,您可以将违规添加到constraintValidatorContext
方法isValid()
中,例如:
Set<ConstraintViolation<SecondaryDTO>> violations = validator.validate(userDTO.getSecondaryDTO());
violations.forEach(violation -> constraintValidatorContext
.buildConstraintViolationWithTemplate(violation.getMessage())
.addConstraintViolation());
推荐阅读
- intellij-idea - Intellij 中文件上的红色方块是什么意思?Scala 错误在新机器上构建项目
- kdb - 在整个表 KDB 中用空值替换无穷大
- python - 如何将 JSON 转换为字符串?
- c++ - 如何在 Godbolt 上使用 Google Benchmark
- c# - 当我尝试选择用户名并将其放入字符串时,为什么 C# 会给我一个错误?
- c - strcpy 给出分段错误
- c - 如何在 C 中打印 .10 而不是 .1?
- android - 为什么 checkAndRepleaceImage 方法不起作用?
- python - Unity WebRequest POST 请求到 python 应用程序 | 如何在python中接收数据?
- javascript - 如何使用 Mustache JS 进行条件渲染?