JSR - 使用Spring Boot对Spring @RestController进行349 bean验证

Sab*_*han 6 java spring-mvc jsr bean-validation spring-boot

我使用Spring引导1.5.2.RELEASE并不能纳入JSR - 349(Bean验证1.1),用于@RequestParam@PathVariable在方法本身.

对于POST请求,如果方法参数是Java POJO,那么注释该参数与@Valid工作正常但注释@RequestParam@PathVariable类似@NotEmpty,@Email不工作.

我有Spring的注释控制器类 @Validated

关于SO有很多问题,我对这个答案发表了评论,认为它不适用于我.

Spring Boot包括 - validation-api-1.1.0.Final.jarhibernate-validator-5.3.4.Final.jar.

我错过了什么吗?

示例代码,

@RequestMapping(method = RequestMethod.GET, value = "/testValidated", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseBean<String> testValidated(@Email @NotEmpty @RequestParam("email") String email) {
    ResponseBean<String> response = new ResponseBean<>();
    response.setResponse(Constants.SUCCESS);
    response.setMessage("testValidated");
    logger.error("Validator Not called");
    return response; 
}
Run Code Online (Sandbox Code Playgroud)

下面的处理程序永远不会被调用当我发送空值或者没有良好形成的电子邮件地址时,email&control总是用in testValidated方法.

@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseBean handle(ConstraintViolationException exception) {

    StringBuilder messages = new StringBuilder();
    ResponseBean response = new ResponseBean();

    exception.getConstraintViolations().forEach(entry -> messages.append(entry.getMessage() + "\n"));

    response.setResponse(Constants.FAILURE);
    response.setErrorcode(Constants.ERROR_CODE_BAD_REQUEST);
    response.setMessage(messages.toString());
    return response;
}
Run Code Online (Sandbox Code Playgroud)

ResponseBean<T> 是我的应用程序特定类.

Sab*_*han 11

经过两天多的不成功的打击和审判,我问过这个问题.由于围绕Spring Validations和JSR验证的混淆,Spring如何调用JSR验证器,JSR标准的变化和支持的验证类型,有很多令人困惑的答案.

最后,这篇文章帮了很多忙.

我分两步解决了问题,

1.将以下bean添加到我的Configuration- 没有这些bean,没有任何作用.

@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
    MethodValidationPostProcessor mvProcessor = new MethodValidationPostProcessor();
    mvProcessor.setValidator(validator());
    return mvProcessor;
}           

@Bean
public LocalValidatorFactoryBean validator() {
    LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
    validator.setProviderClass(HibernateValidator.class);
    validator.afterPropertiesSet();
    return validator;
}
Run Code Online (Sandbox Code Playgroud)

2.在我的控制器上放置Spring的@Validated注释,如下所示,

@RestController
@RequestMapping("/...")
@Validated
public class MyRestController {
}
Run Code Online (Sandbox Code Playgroud)

验证是 - org.springframework.validation.annotation.Validated

此设置不影响同一控制器中的验证@Valid注释,@RequestBody并且这些注释继续按原样运行.

所以现在,我可以触发类似下面的方法的验证MyRestController,

@RequestMapping(method = RequestMethod.GET, value = "/testValidated" , consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseBean<String> testValidated(
        @Email(message="email RequestParam is not a valid email address") 
        @NotEmpty(message="email RequestParam is empty") 
        @RequestParam("email") String email) {
    ResponseBean<String> response = new ResponseBean<>();
    ....
    return response; 
}
Run Code Online (Sandbox Code Playgroud)

我不得不在异常处理程序添加另一个处理程序例外- ConstraintViolationException虽然因为@Validated抛出该异常而@Valid抛出MethodArgumentNotValidException