8

What's the best way to invoke class level JSR-303 constraints that do cross field validation from JSF and have the resulting messages get translated to a FacesMessage and be tied to a particular JSF component based on the PropertyPath in the ConstraintViolation?

rich:graphValidator is close, but it doesn't make use of the PropertyPath. Perhaps MyFaces extval could get me close, but there seems to be a whole extra layer of framework on time of bean-validation, so I avoided it.

Here's a simple example:

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;
    }
}

Picture a form where the information about the car and the driver are input. If the Driver had a license type of ROAD and the Car had a car type of RACE, it'd be ideal to see a resulting validation message be translated into a FacesMessage which is connected to the input for license type, since the message was added to that node using the fluent API of Bean Validation.

4

1 回答 1

0

我们的团队也有同样的问题。你可以看看OmniFaces。我使用来自验证器的代码作为蓝图来构建使用反射调用类级验证器的原型。

于 2012-07-18T09:20:58.370 回答