弹簧控制器:尽管@Valid和@ Size,RequestParam仍未通过验证

时间:2018-12-11 08:08:36

标签: spring rest validation spring-boot

我有一个简单的Controller方法:

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

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

使用这些查询参数测试方法无效。

除最后一个测试外的所有测试都应返回“ 400错误请求”。

"/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)注释被忽略?

2 个答案:

答案 0 :(得分:3)

验证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/ < / p>

答案 1 :(得分:1)

您可以直接使用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
    }

}