gpt4 book ai didi

java - 如何以干净的方式在spring-boot中验证基于另一个属性?

转载 作者:行者123 更新时间:2023-12-01 11:13:43 24 4
gpt4 key购买 nike

我正在Spring Boot 2.3.1.RELEASE Web应用程序中验证REST服务请求/bean。目前,尽管我愿意使用任何其他方式进行验证,但我正在使用Hibernate Validator。
说,我有一个Foo模型,它是在Rest Controller中作为请求收到的。我想验证completionDate是否不是null,那么status应该是“complete”还是“closed”。

@StatusValidate
public class Foo {
private String status;
private LocalDate completionDate;
// getters and setters
}
我创建了一个自定义的类级别注释 @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 {};
}
我创建了 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;
}
}
当我验证 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
});
constraintViolation.getPropertyPath().toString() =>状态 constraintViolation.getInvalidValue() =>(Foo对象)
如何在自定义 status或其他任何地方设置无效值( ConstraintValidator属性的实际值),以便 constraintViolation.getInvalidValue()返回 status属性的值?

有没有一种更好的方法来验证请求有效负载/bean,其中某个属性的验证取决于另一个属性的值?
编辑:
我可以做类似的事情
if(constraintViolation.getPropertyPath().toString().equals("status")) {
errorMessage.setValue(foo.getStatus());
}
但这将涉及维护属性名称的String常量,例如。 "status"。虽然,在 StatusValidator中,我也要设置属性名称 .addPropertyNode("status"),这也是我想避免的。

摘要:
我在寻找解决方案(不一定使用自定义验证或 hibernate validator ),其中
  • 我可以验证其属性取决于其他属性值的json请求者或bean。
  • 我不必在任何地方都将bean属性名称维护为String常量(维护噩梦)。
  • 我可以同时获取无效的属性名称和值。
  • 最佳答案

    您可以使用dynamic payload在约束违反中提供其他数据。可以使用HibernateConstraintValidatorContext进行设置:

    context.unwrap(HibernateConstraintValidatorContext.class)
    .withDynamicPayload(foo.getStatus().toString());
    然后可以将 javax.validation.ConstraintViolation展开为 HibernateConstraintViolation以便检索动态有效负载:
    constraintViolation.unwrap(HibernateConstraintViolation.class)
    .getDynamicPayload(String.class);
    在上面的示例中,我们传递了一个简单的字符串,但是您可以传递一个包含所有所需属性的对象。

    请注意,这仅适用于 Hibernate Validator,后者是Bean验证规范(JSR-303/JSR-349)使用最广泛的实现,并由Spring作为其默认验证提供程序使用。

    关于java - 如何以干净的方式在spring-boot中验证基于另一个属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62981169/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com