Проверка JSR 303 с иерархией - PullRequest
0 голосов
/ 06 ноября 2019

Предположим, у нас есть объект, который расширяет другой, и я хочу создать пользовательскую проверку для обоих, например, объектов Period и PeriodAmount. Где Period:

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

И PeriodAmount:

public class PeriodAmount extends Period {
    private BigDecimal amount;

У меня есть специальный валидатор для Period, например:

    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;

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

У меня есть решение для этого. Я не знаю, является ли это лучшим способом сделать это или есть более элегантный способ, но это работает. Вот что у меня есть:

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;
    }


}

Любые мысли очень приветствуются!

0 голосов
/ 06 ноября 2019

Вы могли бы сделать это проще без специального валидатора:

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
    }
}
...