【问题标题】:Spring Controller: RequestParam not validated despite @Valid and @SizeSpring Controller:尽管有 @Valid 和 @Size,但 RequestParam 未验证
【发布时间】:2018-12-11 08:08:36
【问题描述】:

我有一个简单的控制器方法:

@GetMapping("/search")
    public List<Result> search(@RequestParam @Valid @NotNull @Size(min = 4) String query) {
        return searchService.search(query);
    }

当我省略“查询”参数时,我得到一个 400 错误请求,正如预期的那样。

使用这些查询参数测试方法不起作用。

除最后一个测试外,所有测试都应返回“400 Bad Request”。

"/search"             --> actual 400 Bad Request, test passes
"/search?query="      --> actual 200 Ok, expected 400 because @Size(min=4)
"/search?query=a"     --> actual 200 Ok, expected 400 because @Size(min=4)
"/search?query=ab"    --> actual 200 Ok, expected 400 because @Size(min=4)
"/search?query=abc"   --> actual 200 Ok, expected 400 because @Size(min=4)
"/search?query=abcd"  --> actual 200 Ok, test passes

为什么@Size(min=4) 注释被忽略了?

【问题讨论】:

    标签: spring rest validation spring-boot


    【解决方案1】:

    验证 RequestParameters 不能像开箱即用那样工作。

    你可以将参数包装在一个类中

    class SearchRequest {
        @Size(min=4)
        @NotNull
        private String query;
        ...
    }
    

    然后将您的控制器代码更改为

    @GetMapping("/search")
    public List<Result> search(@ModelAttribute @Valid SearchRequest searchRequest) {
        return searchService.search(searchRequest.getQuery());
    }
    

    现在这是一种方法,您想要的可能可以使用类上的@Validated 注释来实现,但我对此一无所知,但它似乎在这里有所介绍:https://sdqali.in/blog/2015/12/04/validating-requestparams-and-pathvariables-in-spring-mvc/

    【讨论】:

      【解决方案2】:

      您可以使用开箱即用的 RequestParameters 验证)

      您需要将 MethodValidationPostProcessor 添加到您的配置中

      @org.springframework.context.annotation.Configuration
      public class Configuration {
      
          @Bean
          public MethodValidationPostProcessor methodValidationPostProcessor() {
              return new MethodValidationPostProcessor();
          }
      
      }
      

      和@Validated 注解到你的控制器

      @RestController
      @Validated
      public class MyController {
      
          @GetMapping("/search")
          public String search(@RequestParam @NotNull @Size(min = 4) String query) {
              return "success";
          }
      
      }
      

      还请记住,您可能想要处理异常,如果方法参数无效则抛出该异常,您可以这样做

      @ControllerAdvice
      @Component
      public class ExceptionHandler {
          @ExceptionHandler
          @ResponseBody
          @ResponseStatus(HttpStatus.BAD_REQUEST)
          public List handle(MethodArgumentNotValidException exception) {
              //do your stuff here
              return exception.getBindingResult().getFieldErrors()
                      .stream()
                      .map(FieldError::getDefaultMessage)
                      .collect(Collectors.toList()));
          }
      
      
          @ExceptionHandler
          @ResponseBody
          @ResponseStatus(HttpStatus.BAD_REQUEST)
          public List handle(ConstraintViolationException exception) {
             //do your staff here
          }
      
      }
      

      【讨论】:

      • 使用 spring boot v2.这个解决方案对我不起作用。
      猜你喜欢
      • 2020-03-30
      • 1970-01-01
      • 2016-12-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-17
      • 2015-05-01
      • 2012-09-03
      • 1970-01-01
      相关资源
      最近更新 更多