一. 概述
在后端开发中,接口参数总是要做很多校验,很多人都是直接在业务代码层一个个手动
if
判断,这样写一点都不优雅. SpringBoot继承了Hibernate-validator验证框架,可以优雅的进行参数校验
二. 使用
2.1 引入依赖
<!-- Hibernate 参数验证包 -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>xxx</version>
</dependency>
2.2 校验注解说明
注解 | 运行时检查 |
---|---|
@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、Array) |
@Valid | 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个 map,则对其中的值部分进行校验 |
@CreditCardNumber | 对信用卡号进行一个大致的验证 |
被注释的元素必须是电子邮箱地址 | |
@Length(min=, max=) | 被注解的对象必须是字符串的大小必须在制定的范围内 |
@NotBlank | 被注解的对象必须为字符串,不能为空,检查时会将空格忽略 |
@NotEmpty | 被注释的对象必须不为空(数据:String、Collection、Map、Array) |
@Range(min=, max=) | 被注释的元素必须在合适的范围内(数据:BigDecimal、BigInteger、String、byte、short、int、long 和原始类型的包装类) |
@URL(protocol=, host=, port=, regexp=, flags=) | 被注解的对象必须是字符串,检查是否是一个有效的 URL,如果提供了 protocol、host 等,则该 URL 还需满足提供的条件 |
2.3 常规使用
实体类
@Data
public class Base implements Serializable {
private static final long serialVersionUID = 9032441284245467988L;
@NotNull(message = "name不能为空")
private String name;
@NotNull(message = "sex不能为空")
private Integer sex;
@NotNull(message = "age不能为空")
@Max(value = 100,message = "age不能超过100")
private Integer age;
}
控制层
@RestController
@RequestMapping("/test")
public class TestController {
@PostMapping("check")
public AjaxResult check(@RequestBody @Validated Base base){
return AjaxResult.success(base);
}
}
在要校验的参数前加上注解
@Validated
2.4 异常信息处理
全局捕获遗产类型处理
@RestControllerAdvice
@Slf4j
public class ExceptionHandlerAdvice {
@ExceptionHandler(MethodArgumentNotValidException.class)
public AjaxResult constraintViolationException(MethodArgumentNotValidException e){
String defaultMessage = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
return Response.error(defaultMessage);
}
}
在控制层处理异常
@RestController
@RequestMapping("/test")
public class TestController {
@PostMapping("check")
public AjaxResult check(@RequestBody @Validated Base base, BindingResult bindingResult){
if (bindingResult.hasErrors()) {
// 直接获取错误信息
List<String> errors = bindingResult.getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.toList());
//获取参数的属性信息
// List<String> errors = bindingResult.getFieldErrors().stream().map(FieldError::getDefaultMessage).collect(Collectors.toList());
}
return Response.success(base);
}
}
用参数
bindingResult
处理异常信息
2.5 @Validated 和 @Valid 有什么区别
- @Valid 是 Hibernate 提供的效验机制,Java 的 JSR 303 声明了 @Valid 这个类接口,而 Hibernate-validator 对其进行了实现;@Validated 是 Spring 提供的效验机制,@Validation 是对 @Valid 进行了二次封装,提供了分组功能,可以在参数验证时,根据不同的分组采用不同的验证机制;
- @Valid 可用在成员对象的属性字段验证上,而 @Validated 不能用在成员对象的属性字段验证上,也就是说 @Validated 无法提供嵌套验证。
2.6 分组校验
实体类
@Data
public class Base implements Serializable {
private static final long serialVersionUID = 9032441284245467988L;
@NotNull(message = "name不能为空",groups = String.class)
private String name;
@NotNull(message = "sex不能为空",groups = Integer.class)
private Integer sex;
@NotNull(message = "age不能为空",groups = Integer.class)
@Max(value = 100,message = "age不能超过100")
private Integer age;
}
校验注解声明参数
groups
进行分组, 值可以为任意类
控制层
@RestController
@RequestMapping("/test")
public class TestController {
@PostMapping("check")
public AjaxResult check(@RequestBody @Validated(Integer.class) Base base){
return AjaxResult.success(base);
}
}
这样参数就只会校验
sex
和age
网友评论