How to perform Spring validation in MultiActionController?

后端 未结 1 1442
花落未央
花落未央 2021-01-14 11:10

How to perform Spring validation in MultiActionController?

相关标签:
1条回答
  • 2021-01-14 11:43

    Let's write the following one

    public class Person {
    
        private String name;
        private Integer age;
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    

    And your MultiActionController

    import static org.springframework.validation.ValidationUtils.*;
    
    @Component
    public class PersonController extends MultiActionController {
    
        public PersonController() {
            setMethodNameResolver(new InternalPathMethodNameResolver());
    
            setValidators(new Validator[] {new Validator() {
                public boolean supports(Class clazz) {
                    return clazz.isAssignableFrom(Person.class);
                }
    
                public void validate(Object command, Errors errors) {
                    rejectIfEmpty(errors, "age", "", "Age is required");
                    rejectIfEmptyOrWhitespace(errors, "name", "", "Name is required");
                }
    
            }});
        }
    
        public ModelAndView add(HttpServletRequest request, HttpServletResponse response, Person person) throws Exception {
            // do something (save our Person object, for instance)
    
            return new ModelAndView();
        }
    
    }    
    

    MultiActionController defines a property called validators where you should provide any Validator used by your MultiActionController. Here you can see a piece of code which is responsible for validating your Command object inside MultiActionController

    ServletRequestDataBinder binder = ...
    
    if (this.validators != null) 
        for (int i = 0; i < this.validators.length; i++) {
            if (this.validators[i].supports(command.getClass())) {
        ValidationUtils.invokeValidator(this.validators[i], command, binder.getBindingResult());
            }
        }
    }
    
    /**
      * Notice closeNoCatch method
      */
    binder.closeNoCatch();
    

    closeNoCatch method says

    Treats errors as fatal

    So if your Validator returns any Error, closeNoCatch will throw a ServletRequestBindingException. But, you can catch it inside your MultiActionController method, as follows

    public ModelAndView hanldeBindException(HttpServletRequest request, HttpServletResponse response, ServletRequestBindingException bindingException) {
        // do what you want right here
    
        BindException bindException = (BindException) bindingException.getRootCause();
    
        return new ModelAndView("personValidatorView").addAllObjects(bindException.getModel());
    }
    

    In order to test, let's do the following one

    @Test
    public void failureValidation() throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest();
        request.setMethod("POST");
        request.setRequestURI("http://127.0.0.1:8080/myContext/person/add.html");
    
        /**
         * Empty values
         */
        request.addParameter("name", "");
        request.addParameter("age", "");
    
        PersonController personController = new PersonController();
    
        ModelAndView mav = personController.handleRequest(request, new MockHttpServletResponse());
    
        BindingResult bindingResult = (BindingResult) mav.getModel().get(BindingResult.MODEL_KEY_PREFIX + "command");
    
        /**
         * Our Validator rejected 2 Error
         */
        assertTrue(bindingResult.getErrorCount() == 2);
        for (Object object : bindingResult.getAllErrors()) {
            if(object instanceof FieldError) {
                FieldError fieldError = (FieldError) object;
    
                System.out.println(fieldError.getField());
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题