1. 简介
处理一段业务逻辑,首先要确保数据输入的正确性,所以需要先对数据进行检查,保证数据在语义上的正确性,再根据数据进行下一步的处理。
前端可以通过 js 程序校验数据是否合法,后端同样也需要进行校验。而后端最简单的实现就是直接在业务方法中对数据进行处理,但是不同的业务方法可能会出现同样的校验操作,这样就出现了数据的冗余。为了解决这个情况,JSR 303 出现了。
JSR 303 使用 Bean Validation,即在 Bean 上添加相应的注解,去实现数据校验。这样在执行业务方法前,都会根据注解对数据进行校验,从而减少自定义的校验逻辑,减少代码冗余。
2. springboot中JSR的使用
2.1引入依赖
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
|
2.2 构建一个需要校验的java Bean,通过校验注解进行对应的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
|
2.3 添加 @Valid 开启校验
在请求方法中,使用校验注解@Valid,开启校验
1 2 3 4 5 6
| @RequestMapping("/save") public R save(@Valid @RequestBody BrandEntity brand){ brandService.save(brand);
return R.ok(); }
|
想要自定义错误消息,可以覆盖默认的错误提示信息,在添加注解的时候,修改message:
1 2
| @NotBlank(message = "品牌名必须非空") private String name;
|
2.4 BindResult(可选)
给校验的Bean后,紧跟一个BindResult,就可以获取到校验的结果。加完以后,如果参数验证不通过,那就直接进入if语句里面,在语句里面做相应的返回结果.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @RequestMapping("/save") public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){ if( result.hasErrors()){ Map<String,String> map=new HashMap<>(); result.getFieldErrors().forEach((item)->{ String message = item.getDefaultMessage(); String field = item.getField(); map.put(field,message); }); return R.error(400,"提交的数据不合法").put("data",map); }else {
} brandService.save(brand);
return R.ok(); }
|
2.5 定义全局异常类
使用Springboot所提供的@ControllerAdvice,通过“basePackages”能够说明处理哪些路径下的异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
@Slf4j @RestControllerAdvice(basePackages = "com.bigdata..controller") public class GulimallExceptionAdvice {
@ExceptionHandler(value = Exception.class) public R handleValidException(MethodArgumentNotValidException exception){ Map<String,String> map=new HashMap<>(); BindingResult bindingResult = exception.getBindingResult(); bindingResult.getFieldErrors().forEach(fieldError -> { String message = fieldError.getDefaultMessage(); String field = fieldError.getField(); map.put(field,message); });
log.error("数据校验出现问题{},异常类型{}",exception.getMessage(),exception.getClass()); return R.error(400,"数据校验出现问题").put("data",map); }
}
|