调用类级JSR-303约束的最佳方法是什么?这些约束从JSF进行跨字段验证,并将结果消息转换为FacesMessage,并根据ConstraintViolation中的PropertyPath绑定到特定的JSF组件。
rich:graphValidator很接近,但是它没有使用PropertyPath。也许MyFaces的extval可以让我接近,但是在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;
}
}
想象一个表单,其中输入了关于汽车和驾驶员的信息。如果Driver的许可证类型为ROAD, Car的汽车类型为RACE,那么看到结果验证消息被转换为连接到许可证类型输入的FacesMessage是理想的,因为该消息是使用Bean validation的流畅API添加到该节点的。
我们的团队也有同样的问题。你可以看看OmniFaces。我使用来自验证器的代码作为蓝图来构建一个原型,该原型使用反射来调用类级验证器。