Каков наилучший способ вызвать ограничения JSR-303 на уровне класса, которые выполняют перекрестную проверку полей из JSF и получают полученные сообщения, переведенные в FacesMessage и привязанные к конкретному компоненту JSF на основе PropertyPath в ConstraintViolation?
rich:graphValidator близко, но не использует PropertyPath. Возможно, extval MyFaces мог бы приблизить меня, но, похоже, существует целый дополнительный уровень фреймворка во время проверки bean-компонента, поэтому я избегал его.
Вот простой пример:
public enum Type {
ROAD, RACE;
}
public class Driver {
private String name;
private Type licenseType;
...
}
@CarConstraint
public class Car {
@Valid
private Driver driver;
private Type carType;
private String make;
private String model;
...
}
public class CarConstraintValidator implements ConstraintValidator<CarConstraint, Car> {
@Override
public void initialize(CarConstraint constraintAnnotation) {}
@Override
public boolean isValid(Car value, ConstraintValidatorContext context) {
if (value == null) { return true; }
if (Type.RACE.equals(value.getCarType())
&& !Type.RACE.equals(value.getDriver().getLicenseType())) {
context.buildConstraintViolationWithTemplate("Driver of this car must have a racing license")
.addNode("driver")
.addNode("licenseType")
.addConstraintViolation();
return false;
}
return true;
}
}
Представьте себе форму, куда вводится информация об автомобиле и водителе. Если бы у Водителя была лицензия типа ROAD, а у Автомобиля тип автомобиля RACE, было бы идеально увидеть, как результирующее сообщение проверки будет переведено в FacesMessage, которое подключено к входу для типа лицензии, поскольку сообщение было добавлено. к этому узлу, используя свободный API Bean Validation.