假设我们有一个扩展了另一个的对象,并且我想为两个对象创建自定义验证,例如: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;
您可以在没有自定义验证器的情况下更简单地执行此操作:
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
}
}
我原本希望通过在一个接口中添加两个验证器来看到它的工作,如下所示:
@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在层次结构中调用它。我很想听听您的意见。
有效,但这是最佳解决方案吗?