JSR - Spring @RestController 和 Spring Boot 的 349 bean 验证
JSR - 349 bean validation for Spring @RestController with Spring Boot
我正在使用 Spring Boot 1.5.2.RELEASE 并且无法在方法本身为 @RequestParam
和 @PathVariable
合并 JSR-349(bean 验证 1.1)。
对于 POST 请求,如果方法参数是 Java POJO,则使用 @Valid
注释该参数工作正常,但注释 @RequestParam
& @PathVariable
@NotEmpty
、@Email
之类的东西不起作用。
我已经用 Spring 的 @Validated
注释了控制器 class
关于 SO 有很多问题,我在 this answer 上评论说它对我不起作用。
Spring 引导包括 - validation-api-1.1.0.Final.jar
和 hibernate-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;
}
当我为 email
发送空值或格式不正确的电子邮件地址时,永远不会调用下面的处理程序,并且控制总是转到 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;
}
ResponseBean<T>
是我的特定应用 class。
经过两天多的点击和试用失败后,我才提出这个问题。由于围绕 Spring 验证和 JSR 验证、Spring 如何调用 JSR 验证器、JSR 标准的更改以及支持的验证类型的混淆,因此存在许多令人困惑的答案。
最后,this article帮了大忙。
我分两步解决了问题,
1.Added 跟随 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;
}
2.Placed Spring 在我的控制器上的 @Validated 注释如下所示,
@RestController
@RequestMapping("/...")
@Validated
public class MyRestController {
}
验证为 - org.springframework.validation.annotation.Validated
此设置不影响同一控制器中 @RequestBody
验证的 @Valid
注释,并且这些注释继续按原样工作。
现在,我可以为 MyRestController
class、
中的方法触发验证,如下所示
@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;
}
我必须在异常处理程序中为异常添加另一个处理程序 - ConstraintViolationException
尽管因为 @Validated
抛出此异常而 @Valid
抛出 MethodArgumentNotValidException
Spring 添加@Validated 时@Validated @Controller 没有映射。从控制器本身移除任何继承确实有帮助。否则 Sabir Khan 的回答有效并且确实有帮助。
我正在使用 Spring Boot 1.5.2.RELEASE 并且无法在方法本身为 @RequestParam
和 @PathVariable
合并 JSR-349(bean 验证 1.1)。
对于 POST 请求,如果方法参数是 Java POJO,则使用 @Valid
注释该参数工作正常,但注释 @RequestParam
& @PathVariable
@NotEmpty
、@Email
之类的东西不起作用。
我已经用 Spring 的 @Validated
关于 SO 有很多问题,我在 this answer 上评论说它对我不起作用。
Spring 引导包括 - validation-api-1.1.0.Final.jar
和 hibernate-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;
}
当我为 email
发送空值或格式不正确的电子邮件地址时,永远不会调用下面的处理程序,并且控制总是转到 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;
}
ResponseBean<T>
是我的特定应用 class。
经过两天多的点击和试用失败后,我才提出这个问题。由于围绕 Spring 验证和 JSR 验证、Spring 如何调用 JSR 验证器、JSR 标准的更改以及支持的验证类型的混淆,因此存在许多令人困惑的答案。
最后,this article帮了大忙。
我分两步解决了问题,
1.Added 跟随 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;
}
2.Placed Spring 在我的控制器上的 @Validated 注释如下所示,
@RestController
@RequestMapping("/...")
@Validated
public class MyRestController {
}
验证为 - org.springframework.validation.annotation.Validated
此设置不影响同一控制器中 @RequestBody
验证的 @Valid
注释,并且这些注释继续按原样工作。
现在,我可以为 MyRestController
class、
@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;
}
我必须在异常处理程序中为异常添加另一个处理程序 - ConstraintViolationException
尽管因为 @Validated
抛出此异常而 @Valid
抛出 MethodArgumentNotValidException
Spring 添加@Validated 时@Validated @Controller 没有映射。从控制器本身移除任何继承确实有帮助。否则 Sabir Khan 的回答有效并且确实有帮助。