Spring / Hibernate - 手动验证组并返回BindingResult

时间:2013-08-01 07:41:25

标签: spring spring-mvc hibernate-validator

我想使用组手动验证(不使用@Valid或@Validated)并返回BindingResult。

我配置了弹簧验证器

  <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" >
    <property name="validationMessageSource" ref="messageSource"/>
  </bean> 

这是进行验证的类,它可以工作,但注意到groups没有被使用。

@Component
public class ObjectValidatorImpl implements ObjectValidator {
    private final Validator validator;

    @Autowired
    public ObjectValidatorImpl(final Validator validator) {
        super();
        this.validator = validator;
    }

    @Override
    public final <T> BindingResult getBindingResults(
               final T objectToValidate, final Class<?>...groups) {
        final DataBinder binder = new DataBinder(objectToValidate);
        binder.setValidator(validator);

        //ideally, I would like to set the groups on the binder here like
        //binder.setGroups(groups);

        binder.validate();
        return binder.getBindingResult();
    }
}

我无法弄清楚如何让Validator使用这些组,似乎没有方法。

我想这样称呼它。

objectValidator.validate(myObject, Class1.class, Class2.class)

3 个答案:

答案 0 :(得分:2)

我遇到了类似的问题,最后扩展了SpringValidatorAdapter类,以便我可以执行验证并指定组。

ExtendedSpringValidatorAdapter adapter = new ExtendedSpringValidatorAdapter(validator);
adapter.validate(objectToValidate, bindingResult, Class1.class, Class2.class);

以下是扩展验证器的定义:

package com.example.validator;

import org.springframework.beans.NotReadablePropertyException;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.groups.Default;
import java.util.Set;

public class ExtendedSpringValidatorAdapter extends SpringValidatorAdapter {

    // ========================================================================
    // ========================================================================
    // ========================================================================
    public ExtendedSpringValidatorAdapter(Validator targetValidator) {
        super(targetValidator);
    }

    // ========================================================================
    // ========================================================================
    // ========================================================================
    public void validate(Object target, Errors errors, Class<?>... groups) {

        if (groups == null || groups.length == 0 || groups[0] == null) {
            groups = new Class<?>[]{Default.class};
        }

        Set<ConstraintViolation<Object>> result = validate(target, groups);
        for (ConstraintViolation<Object> violation : result) {
            String field = violation.getPropertyPath().toString();
            FieldError fieldError = errors.getFieldError(field);
            if (fieldError == null || !fieldError.isBindingFailure()) {
                try {
                    errors.rejectValue(field,
                            violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName(),
                            getArgumentsForConstraint(errors.getObjectName(), field, violation.getConstraintDescriptor()),
                            violation.getMessage());
                } catch (NotReadablePropertyException ex) {
                    throw new IllegalStateException("JSR-303 validated property '" + field +
                            "' does not have a corresponding accessor for Spring data binding - " +
                            "check your DataBinder's configuration (bean property versus direct field access)", ex);
                }
            }
        }
    }
}

答案 1 :(得分:0)

我认为最简单的方法是使用SmartValidator。您可以像常规Validator一样注入它。通过使用SmartValidator,您将拥有Validation Hints,您可以使用它来传递javax.validation.group作为参数。最终代码可以像这样简单:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.SmartValidator;

@Component
public class FooController {

    @Autowired
    private SmartValidator validator;

    public void validate(MyObject target, Errors errors) {
        validator.validate(target, errors, FirstCheck.class, SecondCheck.class);
    }
}

答案 2 :(得分:0)

从3.1版本开始, org.springframework.validation.DataBinder#validate(java.lang.Object...validationHints)

那就这样做吧

binder.validate(Class1.class, Class2.class);

使用内部方法SmartValidator

if(... validator instanceof SmartValidator) {
   ((SmartValidator) validator).validate(target, bindingResult, validationHints);