spring mvc nested model validation

前端 未结 4 1816
梦毁少年i
梦毁少年i 2020-12-18 10:01

I have two models : User,Project

public class Project{
    private int id;
    @NotEmpty(message=\"Project Name can not be empty\")
    private          


        
相关标签:
4条回答
  • 2020-12-18 10:24

    Actually what you need to do is add @Valid on

    private User manager;
    private User operator;
    

    like this

    @Valid
    private User manager;
    @Valid
    private User operator;
    
    0 讨论(0)
  • 2020-12-18 10:39

    In your Controller you can add a custom validator:

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(new ProjectValidator());
    }
    

    In this validator, you could check the User objects or delegate to a UserValidator, as done here in the last paragraph before section 6.3

    0 讨论(0)
  • 2020-12-18 10:48

    I did what Jerome Dalbert suggested and in addition added a custom BeanValidator for delegating the actual work of validating to a JSR 303 implementation.

    The prefix is used to denote the path of the property in the form.

    @Component
    public class BeanValidator implements org.springframework.validation.Validator, InitializingBean {    
    
     private Validator validator;
     public void afterPropertiesSet() throws Exception {
      ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
      validator = validatorFactory.usingContext().getValidator();
     }
    
     public boolean supports(Class clazz) {
      return true;
     }
    
     public void validate(Object target, Errors errors, String prefix) {
      Set<ConstraintViolation<Object>> constraintViolations = validator.validate(target);
      for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
       String propertyPath = constraintViolation.getPropertyPath().toString();
       String message = constraintViolation.getMessage();
       errors.rejectValue(prefix + "." + propertyPath, "", message);
      }
     }
    
     public void validate(Object target, Errors errors) {
      validate(target, errors, "");
     }
    }
    

    and here how I used it in the UserValidator:

    @Component
    public class UserValidator implements Validator {
    
     @Autowired
     BeanValidator beanValidator;
    
     @Override
     public boolean supports(Class<?> clazz) {
      return User.class.equals(clazz);
     }
    
     @Override
     public void validate(Object target, Errors errors) {
      User user = (User) target;
      beanValidator.validate(user.getAddress(), errors, "address");
     }
    }
    

    References:

    • http://blog.trifork.com/2009/08/04/bean-validation-integrating-jsr-303-with-spring/
    0 讨论(0)
  • 2020-12-18 10:50

    Here's one possible solution.

    Create the class below :

    ...
    import org.springframework.validation.Validator;
    ...
    
    @Component
    public class ProjectValidator implements Validator {
    
        @Override
        public boolean supports(Class<?> clazz) {
            return Project.class.equals(clazz);
        }
    
        @Override
        public void validate(Object target, Errors errors) {
            Project project = (Project) target;
    
            /* Do your checks here */
            ...
    
            if (managerIdDoesNotMatch) {
                errors.rejectValue("manager.id", "your_error_code");
            }
    
            ...
    
            if (operatorIdDoesNotMatch) {
                errors.rejectValue("operator.id", "your_error_code");
            }
    
            ...
        }
    }
    

    And in your controller do something like :

    ...
    public class ProjectController {
    
        @Autowired
        ProjectValidator projectValidator;
    
        ...
    
        @RequestMapping(...)
        public String yourCreateMethod(..., @ModelAttribute @Valid Project project, BindingResult result) {
            projectValidator.validate(project, result);           
    
            if (result.hasErrors()){
              // do something
            }
            else {
              // do something else
            }
        }
    
    }
    

    This should get you started. You could instantiate/set the validator differently, have a a user sub-validator, but you get the general idea.

    References :

    • Latest Spring validation documentation
    • This Stack Overflow post about how to perform validation
    0 讨论(0)
提交回复
热议问题