Smi*_*ile 9 java bean-validation spring-boot
我正在验证 spring-boot 2.3.1.RELEASE Web 应用程序中的 REST 服务请求/bean。目前,我正在使用 Hibernate Validator,但我愿意使用任何其他方式进行验证。
说,我有一个模型Foo,我在Rest Controller. 我想验证如果completionDate不是null那么status应该“完成”或“关闭”。
@StatusValidate
public class Foo {
private String status;
private LocalDate completionDate;
// getters and setters
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个自定义类级别的注释@StatusValidate。
@Constraint(validatedBy = StatusValidator.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface StatusValidate {
String message() default "default status error";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Run Code Online (Sandbox Code Playgroud)
我创建了StatusValidator类。
public class StatusValidator implements ConstraintValidator<StatusValidate, Foo> {
@Override
public void initialize(StatusValidateconstraintAnnotation) {
}
@Override
public boolean isValid(Foovalue, ConstraintValidatorContext context) {
if (null != value.getCompletionDate() && (!value.getStatus().equalsIgnoreCase("complete") && !value.getStatus().equalsIgnoreCase("closed"))) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()).
.addPropertyNode("status").addConstraintViolation();
return false;
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
当我验证Foo对象时(通过使用@Valid或@Validated手动调用该validator.validate()方法),我在ConstraintViolation. 代码:
// Update.class is a group
Set<ConstraintViolation<Foo>> constraintViolations = validator.validate(foo, Update.class);
constraintViolations.forEach(constraintViolation -> {
ErrorMessage errorMessage = new ErrorMessage();
errorMessage.setKey(constraintViolation.getPropertyPath().toString());
errorMessage.setValue(constraintViolation.getInvalidValue());
// Do something with errorMessage here
});
Run Code Online (Sandbox Code Playgroud)
constraintViolation.getPropertyPath().toString() => 状态
constraintViolation.getInvalidValue() => (Foo 对象)
如何status在自定义ConstraintValidator或其他任何地方设置无效值(属性的实际值)以便constraintViolation.getInvalidValue()返回status属性值?
或者
是否有更好的方法来验证请求有效负载/bean,其中属性的验证取决于另一个属性的值?
编辑: 我可以做类似的事情
if(constraintViolation.getPropertyPath().toString().equals("status")) {
errorMessage.setValue(foo.getStatus());
}
Run Code Online (Sandbox Code Playgroud)
但这将涉及在某处维护属性名称的字符串常量,例如。"status". 尽管如此,StatusValidator我也在设置属性名称.addPropertyNode("status"),这也是我想避免的。
摘要: 我正在寻找解决方案(不一定使用自定义验证或休眠验证器),其中
您可以使用动态负载在约束违规中提供附加数据。可以使用以下方式设置HibernateConstraintValidatorContext:
context.unwrap(HibernateConstraintValidatorContext.class)
.withDynamicPayload(foo.getStatus().toString());
Run Code Online (Sandbox Code Playgroud)
并且javax.validation.ConstraintViolation可以依次解包HibernateConstraintViolation以检索动态负载:
constraintViolation.unwrap(HibernateConstraintViolation.class)
.getDynamicPayload(String.class);
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,我们传递一个简单的字符串,但您可以传递一个包含您需要的所有属性的对象。
请注意,这仅适用于Hibernate Validator,它是 Bean Validation 规范 (JSR-303/JSR-349) 使用最广泛的实现,并被 Spring 用作其默认验证提供程序。
| 归档时间: |
|
| 查看次数: |
5435 次 |
| 最近记录: |