之前写小项目时,遇到前后端交互数据,每次都要对每个字段进行格式验证,而且验证的步骤和代码大都是千篇一律。今天接触到了hibernate validator
验证框架,今后就能摆脱这种烦人的情况了。
hibernate validator的依赖在spring-boot-starter-web
中,所以无需另外引入依赖。
类属性验证示例代码
public class DemoModel {
@NotBlank(message = "姓名不能为空")
private String userName;
@NotBlank(message = "年龄不能为空")
@Pattern(regexp = "^[0-9]{1,2}$",message="年龄不正确")
private String age;
@Email
private String email;
...省略get set
}
//这里由于使用Postman使用JSON数据,所以要使用@RequestBody,如果是表单数据且数类属性,直接@Valid DemoModel demo即可
@RequestMapping(value = "/demo2",method = RequestMethod.POST)
public void demo2(@RequestBody @Valid DemoModel demo, BindingResult result){
if(result.hasErrors()){
for (ObjectError error : result.getAllErrors()) {
System.out.println(error.getDefaultMessage());
}
}
}
result里封装着检验不通过的信息,对于检验不通过可分为两种,一种是对所有字段都检验完,封装所有的错误信息,还有一种是一检验到不合格字段就返回,剩余字段不再检验,默认是第一种,下面配置第二种快速检验。
@Configuration
public class ValidatorConfiguration {
@Bean
public Validator validator(){
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
.addProperty( "hibernate.validator.fail_fast", "true" )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
}
统一进行异常处理
在controller如果每次都要对错误信息遍历也是相当麻烦,因此在统一异常处理类捕捉MethodArgumentNotValidException
即可,这个exception内部也封装了BindResult,BindingResult result = ((MethodArgumentNotValidException) e).getBindingResult();
统一在异常处理类进行遍历返回,对于普通的表单验证抛出的是BindException
上面的代码只适合于类属性数据的验证,如果是单个参数数据的验证上述方法是不可行的。
参数验证实例代码
先在config类加上配置,表示要使用参数验证
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
在类上使用注解@Validated
@Validated
@RestController
public class GirlController。。。。
在参数前进行注解验证
@RequestMapping(value = "/demo2",method = RequestMethod.POST)
public String demo2(@Email @RequestParam String email){
return email;
}
统一进行异常处理
并且此时如果验证不通过,抛出的异常不再是上面那个异常,而是ConstraintViolationException
,所以在异常类进行处理时,对于这个exception也要进行处理,并且这个exception封装的异常信息也再是BindResult,而是下面的这个Set。
Set<ConstraintViolation<?>> constraintViolations = ((ConstraintViolationException) e).getConstraintViolations();
StringBuilder errorMsg = new StringBuilder();
for (ConstraintViolation<?> violation : constraintViolations) {
errorMsg.append(violation.getMessage()).append(",");
}
总结
一般对请求的验证有三种,相应的捕捉错误返回错误信息。
- POST使用JSON格式,抛出
MethodArgumentNotValidException
- POST表单验证,抛出
BindException
- 对单个参数进行验证,抛出
ConstraintViolationException