具有层次结构的JSR 303验证

问题描述 投票:0回答:2

假设我们有一个扩展了另一个的对象,并且我想为两个对象创建自定义验证,例如:Period和PeriodAmount对象。期间为:

public class Period {
    private LocalDate startDate;
    private LocalDate endDate;

并且PeriodAmount为:

public class PeriodAmount extends Period {
    private BigDecimal amount;

我有一个用于期间的自定义验证器,例如:

    public class PeriodValidator implements ConstraintValidator<ValidPeriod, Period> {

    @Override
    public boolean isValid(Period period, ConstraintValidatorContext context) {
        LocalDate startDate = period.getStartDate();
        LocalDate endDate = period.getEndDate();

        if (startDate == null) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("{invalid.start.date.null}").addConstraintViolation();
            return false;
        }
        if (endDate != null && startDate.isAfter(endDate)) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("{invalid.end.date.value}").addConstraintViolation();
            return false;
        }
        return true;
    }

}

这非常适合期间。但是现在我想要一个针对PeriodAmount的自定义验证器,并且我想重用我已经用于Period验证的代码。我该怎么做才能只调用一个验证并验证所有内容:

@ValidPeriodAmount
private PeriodAmount periodAmount;
java spring-boot validation bean-validation
2个回答
0
投票

您可以在没有自定义验证器的情况下更简单地执行此操作:

public class Period {
    @NotNull
    private LocalDate startDate;

    private LocalDate endDate;

    @AssertTrue
    public boolean isValid(){
        return endDate == null || endDate.isAfter(startDate);
    }
}

public class PeriodAmount extends Period{

    @AssertTrue
    public boolean isValid(){
        return super.isValid() && //some other condition
    }
}

0
投票

我原本希望通过在一个接口中添加两个验证器来看到它的工作,如下所示:

@Constraint(validatedBy = { PeriodValidator.class, PeriodAmountValidator.class })

但是,当然,这不起作用(也许我遗漏了什么?),并显示错误:

 "message": "HV000243: Constraint be.mloz.ws.model.validation.ValidPeriodAmount references constraint validator type be.mloz.ws.model.validation.PeriodValidator, but this validator is defined for constraint type be.mloz.ws.model.validation.ValidPeriod." 

[好,我对此有一个解决方案,但是我仍然怀疑这是最好的方法,还是还有更优雅的方法。这是我取得的成就:

public class PeriodAmountValidator implements ConstraintValidator<ValidPeriodAmount, PeriodAmount> {


    @Override
    public boolean isValid(PeriodAmount periodAmount, ConstraintValidatorContext context) {
        PeriodValidator validator = new PeriodValidator();
        if (!validator.isValid(periodAmount, context)) {
            return false;
        }

        BigDecimal amount = periodAmount.getAmount();
        if (amount == null) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("{invalid.amount.null}").addConstraintViolation();
            return false;
        }
        if (amount.intValue() <= 0) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("{invalid.amount.value}").addConstraintViolation();
            return false;
        }
        return true;
    }


}

这似乎是一种解决方法,因为我没有使用super在层次结构中调用它。我很想听听您的意见。

有效,但这是最佳解决方案吗?

© www.soinside.com 2019 - 2024. All rights reserved.