Spring验证-类级别验证以解决字段错误

Lpp*_*Edd 3 java validation spring spring-validator

如果我们定义一个类级别的验证批注,例如一个比较字段并具有ConstraintValidator如下内容的批注:

public class ComparisonValidator implements ConstraintValidator<ValueMatches, Object>
{
    private String[] fields;

    @Override
    public void initialize(final ValueMatches constraintAnnotation) {
        fields = constraintAnnotation.fields();
    }

    @Override
    public boolean isValid(final Object value, final ConstraintValidatorContext context) {
        if (fields.length == 0) {
            return true;
        }

        final BeanWrapperImpl beanWrapper = new BeanWrapperImpl(value);
        final Object comparisonValue = beanWrapper.getPropertyValue(fields[0]);

        for (int i = 1; i < fields.length; i++) {
            final Object fieldValue = beanWrapper.getPropertyValue(fields[i]);

            if (!comparisonValue.equals(fieldValue)) {
                return false;
            }
        }

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们很好地产生了一个全局验证错误,可以通过Thymeleaf使用以下命令进行访问: ${#fields.errors('global')}

现在,我如何识别该错误并了解它是特定的比较错误?我的意思是,毕竟我们会收到有关全局错误的消息,还是我错了?

Lpp*_*Edd 5

该死,Spring文档!这相当简单,但并不是真正可以理解的。

@Override
public boolean isValid(final Object value, final ConstraintValidatorContext context) {
    if (fields.length > 0) {
        final BeanWrapperImpl beanWrapper = new BeanWrapperImpl(value);
        final Object comparisonValue = beanWrapper.getPropertyValue(fields[0]);

        for (int i = 1; i < fields.length; i++) {
            if (!comparisonValue.equals(beanWrapper.getPropertyValue(fields[i]))) {
                context.disableDefaultConstraintViolation();
                context.buildConstraintViolationWithTemplate(errorMessage).addPropertyNode(fields[0]).addConstraintViolation();
                return false;
            }
        }
    }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

该方法通过使用注释本身来disableDefaultConstraintViolation()告知ConstrainValidatorContext不要产生约束违反对象。

然后,您可以通过buildConstraintViolationWithTemplate()方法产生自定义约束违规。