4

我想使用组手动验证(不使用@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();
    }
}

我不知道如何让验证器使用这些组,这似乎没有办法。

我想这样称呼它。

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

3 回答 3

3

我遇到了类似的问题,最终扩展了 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);
                }
            }
        }
    }
}
于 2013-08-01T09:48:50.663 回答
1

我认为最简单的方法是使用SmartValidator。你可以像普通的Validator一样注入它。通过使用 SmartValidator ,您可以获得Validation Hints,您可以使用它来传递javax.validation.groupas 参数。最终的代码可以像这样简单:

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);
    }
}
于 2020-11-06T16:08:59.527 回答
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);
于 2020-12-16T21:27:34.443 回答