Spring validation for RequestBody parameters bound to collections in Controller methods

后端 未结 3 610
遇见更好的自我
遇见更好的自我 2020-12-10 16:32

I have

An Entity:

package org.ibp.soq;

public class MyEntity {

    private String field1;
    private String field2;

    //..get         


        
3条回答
  •  感动是毒
    2020-12-10 17:09

    The solution is to create a custom Validator for Collection and a @ControllerAdvice that registers that Validator in the WebDataBinders.

    Validator:

    import java.util.Collection;
    
    import org.springframework.validation.Errors;
    import org.springframework.validation.ValidationUtils;
    import org.springframework.validation.Validator;
    import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
    
    /**
     * Spring {@link Validator} that iterates over the elements of a 
     * {@link Collection} and run the validation process for each of them
     * individually.
     *   
     * @author DISID CORPORATION S.L. (www.disid.com)
     */
    public class CollectionValidator implements Validator {
    
      private final Validator validator;
    
      public CollectionValidator(LocalValidatorFactoryBean validatorFactory) {
        this.validator = validatorFactory;
      }
    
      @Override
      public boolean supports(Class clazz) {
        return Collection.class.isAssignableFrom(clazz);
      }
    
      /**
       * Validate each element inside the supplied {@link Collection}.
       * 
       * The supplied errors instance is used to report the validation errors.
       * 
       * @param target the collection that is to be validated
       * @param errors contextual state about the validation process
       */
      @Override
      @SuppressWarnings("rawtypes")
      public void validate(Object target, Errors errors) {
        Collection collection = (Collection) target;
        for (Object object : collection) {
          ValidationUtils.invokeValidator(validator, object, errors);
        }
      }
    }
    

    ControllerAdvice:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.InitBinder;
    
    /**
     * Controller advice that adds the {@link CollectionValidator} to the 
     * {@link WebDataBinder}.
     * 
     * @author DISID CORPORATION S.L. (www.disid.com)
     */
    @ControllerAdvice
    public class ValidatorAdvice {
    
      @Autowired
      protected LocalValidatorFactoryBean validator;
    
    
      /**
       * Adds the {@link CollectionValidator} to the supplied 
       * {@link WebDataBinder}
       * 
       * @param binder web data binder.
       */
      @InitBinder
      public void initBinder(WebDataBinder binder) {
        binder.addValidators(new CollectionValidator(validator));
      }
    }
    

提交回复
热议问题