В игре! Framework 2.6 Я реализовал следующую форму, для которой требуется настраиваемая проверка:
@Validate
public class MachineRegistrationForm implements Validatable<List<ValidationError>> {
@Required
private String field1;
@Required
private String field2;
// other fields, getters and setters
@Override
public List<ValidationError> validate() {
// validation on field1 and field2
}
}
Похоже, Play выполняет мою настраиваемую проверку перед, проверяя, действительно ли поля @Required поле1 и поле2 содержат некоторые значения, заставляя меня проверять, являются ли значения нулевыми, чтобы избежать NullPointerExceptions. Я придерживаюсь неправильного подхода к пользовательской проверке или это игра! непреднамеренное поведение?




TL; DR: RTFM ;-)
В вашем примере метод validate() не оценивается перед двумя ограничениями @Required: три ограничения вызываются одновременно, поэтому в основном нет гарантированного порядка, который будет выполняться первым. Это также задокументировано в Play Framework документация:
Also be aware that in this example the
validatemethod and the@Constraints.Requiredconstraint will be called simultaneously - so the validate method will be called no matter if@Constraints.Requiredwas successful or not (and vice versa). You will learn how to introduce an order later on.
Если вы внимательно прочитаете документацию, то найдете раздел «Определение порядка групп ограничений»:
You can validate groups in sequences. This means groups will be validated one after another - but the next group will only be validated if the previous group was validated successfully before. (However right now it’s not possible to determine the order of how constraints will be validated within a group itself...)
Чтобы это сработало на вашем примере, давайте улучшим группу ...
public interface First { }
...а также...
public interface Second { }
... и вам понадобится следующая групповая последовательность:
import javax.validation.GroupSequence;
import javax.validation.groups.Default;
@GroupSequence({ Default.class, First.class, Second.class })
public interface OrderedChecks { }
Затем вам нужно добавить группы к вашим ограничениям:
@Validate(groups = {Second.class})
public class MachineRegistrationForm implements Validatable<List<ValidationError>> {
@Required // Default group is Default.class
private String field1;
@Required(groups = {First.class})
private String field2;
// other fields, getters and setters
@Override
public List<ValidationError> validate() {
// validation on field1 and field2
}
}
Теперь вы можете запустить проверку в определенном порядке:
Form<MachineRegistrationForm> form = formFactory().form(MachineRegistrationForm.class, OrderedChecks.class).bindFromRequest();
Теперь сначала будет проверяться field1, и только в случае успеха будет проверяться field2, и только в случае успеха будет проверяться метод validate. Вы также можете удалить (groups = {First.class}) из field2 (так что у него также есть группа Default.class по умолчанию) или же, наоборот, добавьте (groups = {First.class}) в field1 - в обоих случаях теперь два поля будут оцениваться одновременно - и только если оба успешны, то validate будет оцениваться.