Spring Web MVC - validate individual request params

后端 未结 3 497
太阳男子
太阳男子 2020-11-27 03:31

I\'m running a webapp in Spring Web MVC 3.0 and I have a number of controller methods whose signatures are roughly as follows:

@RequestMapping(value = \"/{le         


        
相关标签:
3条回答
  • 2020-11-27 04:15

    This seems to be possible now (tried with Spring 4.1.2), see https://raymondhlee.wordpress.com/2015/08/29/validating-spring-mvc-request-mapping-method-parameters/

    Extract from above page:

    1. Add MethodValidationPostProcessor to Spring @Configuration class:

      @Bean
      public MethodValidationPostProcessor methodValidationPostProcessor() {
          return new MethodValidationPostProcessor();
      }
      
    2. Add @Validated to controller class

    3. Use @Size just before @RequestParam

      @RequestMapping("/hi")
      public String sayHi(@Size(max = 10, message = "name should at most 10 characters long") @RequestParam("name") String name) {
          return "Hi " + name;
      

      }

    4. Handle ConstraintViolationException in an @ExceptionHandler method

    0 讨论(0)
  • 2020-11-27 04:16

    There's nothing built in to do that, not yet anyway. With the current release versions you will still need to use the WebDataBinder to bind your parameters onto an object if you want automagic validation. It's worth learning to do if you're using SpringMVC, even if it's not your first choice for this task.

    It looks something like this:

    public ModelAndView createFoo(@PathVariable long level1,
            @PathVariable long level2,
            @Valid @ModelAttribute() FooWrapper fooWrapper,
            BindingResult errors) {
      if (errors.hasErrors() {
         //handle errors, can just return if using Spring form:error tags.
      }
    }
    
    public static class FooWrapper {
      @NotNull
      @Size(max=32)
      private String fooName;
      private String description;
    //getset
    }
    

    If you have Hibernate Validator 4 or later on your classpath and use the default dispatcher setup it should "Just work."

    Editing since the comments were getting kind of large:

    Any Object that's in your method signature that's not one of the 'expected' ones Spring knows how to inject, such as HttpRequest, ModelMap, etc, will get data bound. This is accomplished for simple cases just by matching the request param names against bean property names and calling setters. The @ModelAttribute there is just a personal style thing, in this case it isn't doing anything. The JSR-303 integration with the @Valid on a method parameter wires in through the WebDataBinder. If you use @RequestBody, you're using an object marshaller based on the content type spring determines for the request body (usually just from the http header.) The dispatcher servlet (AnnotationMethodHandlerAdapter really) doesn't have a way to 'flip the validation switch' for any arbitrary marshaller. It just passes the web request content along to the message converter and gets back a Object. No BindingResult object is generated, so there's nowhere to set the Errors anyway.

    You can still just inject your validator into the controller and run it on the object you get, it just doesn't have the magic integration with the @Valid on the request parameter populating the BindingResult for you.

    0 讨论(0)
  • 2020-11-27 04:30

    If you have multiple request parameters that need to be validated (with Http GET or POST). You might as well create a custom model class and use @Valid along with @ModelAttribute to validate the parameters. This way you can use Hibernate Validator or javax.validator api to validate the params. It goes something like this:

    Request Method:

    @RequestMapping(value="/doSomething", method=RequestMethod.GET)
    public Model dosomething(@Valid @ModelAttribute ModelRequest modelRequest, BindingResult result, Model model) {
    
        if (result.hasErrors()) {
            throw new SomeException("invalid request params");
        }
    
        //to access the request params
        modelRequest.getFirstParam();
        modelRequest.getSecondParam();
    
        ...   
    }
    

    ModelRequest class:

    class ModelRequest {
    
        @NotNull
        private String firstParam;
    
        @Size(min = 1, max = 10, message = "You messed up!")
        private String secondParam;
    
        //Setters and getters
    
        public void setFirstParam (String firstParam) {
            this.firstParam = firstParam;
        }
    
        public String getFirstParam() {
            return firstParam;
        }
    
        ...
    }
    

    Hope that helps.

    0 讨论(0)
提交回复
热议问题