Ограничения Java Bean Validation (JSR303), включающие взаимосвязь между несколькими свойствами bean-компонента - PullRequest
21 голосов
/ 09 ноября 2009

Скажите, у меня есть следующий простой боб Java:

class MyBean {
   private Date startDate;
   private Date endDate;
   //setter, getters etc...
}

Есть ли в JSR 303 механизм для создания пользовательского валидатора, который проверяет ограничение, которое startDate должно быть перед endDate?

Мне кажется, что это обычный случай использования, но я не могу найти никаких примеров такого рода ограничений на отношения между несколькими свойствами.

Ответы [ 5 ]

28 голосов
/ 09 ноября 2009

Я могу придумать несколько вещей, которые можно попробовать.

Вы можете создать Constraint с целью самого типа с соответствующим валидатором:

@ValidateDateRange(start="startDate", end="endDate")
public class MyBean {

Вы можете инкапсулировать диапазон дат в типе и проверить, что:

public class DateRange {    
  private long start;
  private long end;

  public void setStart(Date start) {
    this.start = start.getTime();
  }

  // etc.

Вы можете добавить простое свойство, которое выполняет проверку:

public class MyBean {
  private Date startDate;
  private Date endDate;

  @AssertTrue public boolean isValidRange() {
    // TODO: null checks
    return endDate.compareTo(startDate) >= 0;
  }
11 голосов
/ 05 февраля 2011

Если вы используете Hibernate Validator в версии 4.1 или более поздней, вы можете использовать ограничение @ ScriptAssert вместе с языком сценариев или выражений для выражения этого вида ограничения. Используя JavaScript, ваш пример будет выглядеть так:

 @ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")
 public class CalendarEvent {

      private Date startDate;

      private Date endDate;

      //...
 } 

С помощью вы можете получить еще более компактный синтаксис, создав пользовательское ограничение для выбранного вами языка сценариев:

@JexlAssert("_.startDate < _.endDate")
public class CalendarEvent {

    private Date startDate;

    private Date endDate;

    //...
}
3 голосов
/ 09 ноября 2009

Ответ - валидатор уровня класса. Вы можете определить пользовательские ограничения, которые вы можете наложить на класс сущности. Во время проверки вы передаете весь экземпляр в метод isValid (). Затем вы можете сравнить свои две даты друг с другом. См. Также документацию Hibernate Validator .

0 голосов
/ 09 ноября 2009

Поскольку в валидаторе JSR 303. нет доступа к компоненту, это невозможно.

Обходной путь может заключаться в предоставлении собственного ConstraintValidatorContext и расширении его ссылкой на компонент, который вы в настоящее время проверяете. Но я не уверен, что вы можете изменить / переопределить соответствующую фабрику.

...