Spring Boot Validation统一参数校验
实现方式
使用 @Validated
注解配合参数校验注解, 比如:@NotEmpty
对参数进行校验。然后对抛出的异常ControllerAdvice
进行捕获然后调整输出数据。
1、引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
2、添加注解
2.1 对整个Controller类内所有接口参数校验
@Validated @RestController public class TestController { }
2.2 对单一接口的所有参数校验
@Validated @RequestMapping("/test") public void test(@NotEmpty String uuid,@NotEmpty String name){ }
2.3 json请求
@RequestMapping("/test") public ApiResult json(@RequestBody @Validated Map<String,Object> params){ return ApiResult.success(); }
抛出异常:MethodArgumentNotValidException
2.4 表单提交请求
@GetMapping("/get") public ApiResult get(@Validated @NotEmpty String uuid) { return ApiResult.success(); }
抛出异常:BindException
2.5 表单提交请求(@RequestParam)
@GetMapping("/get") public ApiResult get(@RequestParam @Validated @NotEmpty String uuid) { return ApiResult.success(); }
抛出异常:ConstraintViolationException
3、全局异常处理
/** * 统一异常处理 */ @ControllerAdvice public class ExceptionInterceptor { @ExceptionHandler(ConstraintViolationException.class) @ResponseBody public ApiResult handleConstraintViolationException(ConstraintViolationException e) { String errorMsg = e.getConstraintViolations().stream() .map(cv -> cv == null ? "null" : cv.getPropertyPath() + ": " + cv.getMessage()) .collect(Collectors.joining(", ")); return ApiResult.failureWithCode(400, "参数异常:" + errorMsg); } @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody public ApiResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { String errorField = e.getBindingResult().getFieldErrors().get(0).getField(); String errorMsg = e.getBindingResult().getFieldErrors().get(0).getDefaultMessage(); errorMsg = "[" + errorField + "]" + errorMsg; return ApiResult.failureWithCode(400, "参数异常:" + errorMsg); } @ExceptionHandler(BindException.class) @ResponseBody public ApiResult handleBindException(BindException e) { String errorField = e.getBindingResult().getFieldErrors().get(0).getField(); String errorMsg = e.getBindingResult().getFieldErrors().get(0).getDefaultMessage(); errorMsg = "[" + errorField + "]" + errorMsg; return ApiResult.failureWithCode(400, "参数异常:" + errorMsg); } @ExceptionHandler(Exception.class) @ResponseBody public ApiResult handleException(Exception e) { return ApiResult.failure(e.getMessage()); } }
4、常用校验注解
注解 | 运行时检查 |
---|---|
@AssertFalse | 被注解的元素必须为false |
@AssertTrue | 被注解的元素必须为true |
@DecimalMax(value) | 被注解的元素必须为一个数字,其值必须小于等于指定的最小值 |
@DecimalMin(Value) | 被注解的元素必须为一个数字,其值必须大于等于指定的最小值 |
@Digits(integer=, fraction=) | 被注解的元素必须为一个数字,其值必须在可接受的范围内 |
@Future | 被注解的元素必须是日期,检查给定的日期是否比现在晚 |
@Max(value) | 被注解的元素必须为一个数字,其值必须小于等于指定的最小值 |
@Min(value) | 被注解的元素必须为一个数字,其值必须大于等于指定的最小值 |
@NotNull | 被注解的元素必须不为null |
@Null | 被注解的元素必须为null |
@Past(java.util.Date/Calendar) | 被注解的元素必须过去的日期,检查标注对象中的值表示的日期比当前早 |
@Pattern(regex=, flag=) | 被注解的元素必须符合正则表达式,检查该字符串是否能够在match指定的情况下被regex定义的正则表达式匹配 |
@Size(min=, max=) | 被注解的元素必须在制定的范围(数据类型:String, Collection, Map and arrays) |
@Valid | 递归的对关联对象进行校验, 如果关联对象是个集合或者数组, 那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验 |
@CreditCardNumber | 对信用卡号进行一个大致的验证 |
被注释的元素必须是电子邮箱地址 | |
@Length(min=, max=) | 被注解的对象必须是字符串的大小必须在制定的范围内 |
@NotBlank | 被注解的对象必须为字符串,不能为空,检查时会将空格忽略 |
@NotEmpty | 被注释的对象必须为空(数据:String,Collection,Map,arrays) |
@Range(min=, max=) | 被注释的元素必须在合适的范围内 (数据:BigDecimal, BigInteger, String, byte, short, int, long and 原始类型的包装类 ) |
@URL(protocol=, host=, port=, regexp=, flags=) | 被注解的对象必须是字符串,检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件 |
5、@Valid和@Validated的区别
参考 :https://www.jianshu.com/p/1dff31a1649d