Ограничения проверки Java Bean (JSR303), включающие взаимосвязь между несколькими свойствами bean-компонентов.
-
19-09-2019 - |
Вопрос
Скажем, у меня есть следующий простой Java-компонент:
class MyBean {
private Date startDate;
private Date endDate;
//setter, getters etc...
}
Есть ли в JSR 303 механизм создания специального средства проверки, проверяющего ограничение, согласно которому startDate должно быть раньше endDate?
Мне кажется, это распространенный вариант использования, но я не могу найти примеров такого рода ограничений на множественные отношения свойств.
Решение
Я могу придумать несколько вещей, которые стоит попробовать.
Вы можете создать 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;
}
Другие советы
Если вы используете Спящий валидатор в версии 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;
//...
}
Ответ — валидатор уровня класса.Вы можете определить собственные ограничения, которые вы можете разместить в классе сущности.Во время проверки вы передаете весь экземпляр в метод isValid().Затем вы можете сравнить две даты друг с другом.См. также Валидатор Hibernate. документация.
Поскольку нет возможности получить доступ к компоненту в валидаторе JSR 303, это невозможно.
Обходной путь — предоставить свой собственный ConstraintValidatorContext
и расширите его ссылкой на компонент, который вы сейчас проверяете.Но я не уверен, можете ли вы изменить/переопределить соответствующую фабрику.