Validate a list of nested objects with Spring validator?

后端 未结 4 1430
别那么骄傲
别那么骄傲 2020-12-29 05:38

I want to know how to validate a list of nested objects in my form with Spring Validator (not annotation) in Spring MVC application.

class MyForm() {
    St         


        
相关标签:
4条回答
  • 2020-12-29 06:20

    You can use this anywhere in the project

    import org.springframework.validation.ValidationUtils;
    import org.apache.commons.beanutils.PropertyUtils;
    import org.apache.commons.collections.CollectionUtils;
    
        public static void invokeValidatorForNestedCollection(Validator validator,
                                                          Object obj,
                                                          String collectionPath,
                                                          Errors errors) {
    
        Collection collection;
        try {
            collection = (Collection) PropertyUtils.getProperty(obj, collectionPath);
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    
        if (CollectionUtils.isEmpty(collection)) return;
        int counter = 0;
        for (Object elem : collection) {
            errors.pushNestedPath(String.format(collectionPath + "[%d]", counter));
            ValidationUtils.invokeValidator(validator, elem, errors);
            errors.popNestedPath();
            counter++;
        }
    }
    
    0 讨论(0)
  • 2020-12-29 06:25

    For the nested validation, you can do as below:

    public class MyFormValidator implements Validator {
    
        private TypeAValidator typeAValidator;
    
        @Override
        public boolean supports(Class clazz) {
            return MyForm.class.equals(clazz);
        }
    
        @Override
        public void validate(Object target, Errors errors) {
            MyForm myForm = (MyForm) target;
            typeAValidator = new TypeAValidator();
    
            int idx = 0;
            for (TypeA item : myForm.getListObjects()) {
    
                errors.pushNestedPath("listObjects[" + idx + "]");
                ValidationUtils.invokeValidator(this.typeAValidator, item, errors);
                errors.popNestedPath();
                idx++;
    
                ...
            }
    
            ...
        }
    }
    
    public class TypeAValidator implements Validator{
    
        @Override
        public boolean supports(Class<?> clazz) {
            return TypeA.class.isAssignableFrom(clazz);
        }
    
        @Override
        public void validate(Object target, Errors errors) {
            TypeA objTypeA = (TypeA)target;
    
            ValidationUtils.rejectIfEmpty(errors, "number", "number.notEmpty");
        }
    }
    

    Hope this helps.

    0 讨论(0)
  • public class MyFormValidator implements Validator {
    
        @Override
        public boolean supports(Class clazz) {
            return MyForm.class.equals(clazz);
        }
    
        @Override
        public void validate(Object target, Errors errors) {
            MyForm myForm = (MyForm) target;
    
            for (int i = 0; i < myForm.getListObjects().size(); i++) {
                TypeA typeA = myForm.getListObjects().get(i);
    
                if(typeAHasAnErrorOnNumber) {
                    errors.rejectValue("listObjects[" + i + "].number", "your_error_code");
                }
    
                ...
            }
    
            ...
        }
    
    }
    

    Interesting links :

    • Spring MVC: Multiple Row Form Submit using List of Beans
    0 讨论(0)
  • 2020-12-29 06:41

    A handy helper class that I use -

    public final class ValidationHelper {
    
        public static <TEntity> void invokeNestedValidator(Validator validator, TEntity entity, Errors errors, String subPath) {
            try {
                errors.pushNestedPath(subPath);
                ValidationUtils.invokeValidator(validator, entity, errors);
            } finally {
                errors.popNestedPath();
            }
        }
    
        public static <TEntity> void invokeNestedValidatorForList(Validator validator, List<TEntity> entities, Errors errors, String subPathRoot) {
            for (int index = 0; index < entities.size(); index++) {
                invokeNestedValidator(validator, entities.get(index), errors, subPathRoot + "[" + index + "]");
            }
        }
    
        private ValidationHelper() {}
    }
    
    0 讨论(0)
提交回复
热议问题