参数校验是我们程序开发中必不可少的过程。用户在前端页面上填写表单时,前端js程序会校验参数的合法性,当数据到了后端,为了防止恶意操作,保持程序的健壮性,后端同样需要对数据进行校验。后端参数校验最简单的做法是直接在业务方法里面进行判断,当判断成功之后再继续往下执行。但这样带给我们的是代码的耦合,冗余。当我们多个地方需要校验时,我们就需要在每一个地方调用校验程序,导致代码很冗余,且不美观。那么如何优雅的对参数进行校验呢?JSR303就是为了解决这个问题出现的,主要是介绍 JSR303,Hibernate Validator 等校验工具的使用,以及自定义校验注解的使用。
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.17.Final</version>
</dependency>
Bean Validation 注解
Bean Validation 中内置的 constraint
Constraint | 详细信息 |
---|---|
@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) | 被注释的元素必须符合指定的正则表达式 |
Hibernate Validator 附加的 constraint
Constraint | 详细信息 |
---|---|
被注释的元素必须是电子邮箱地址 | |
@Length | 被注释的字符串的大小必须在指定的范围内 |
@NotEmpty | 被注释的字符串的必须非空 |
@Range | 被注释的元素必须在合适的范围内 |
对象校验
@Valid:开启校验
一般用在controller层居多,如下图位置中:
注意:不加则未起作用哦
那开启对象校验有什么作用呢?
以Driver实体类中的手机号字段为例:
在phone字段上面添加@NotEmpty注解,表示判断该字段不能为空,等同于下图中:
也就是现在可以直接使用@NotEmpty注解代替上图标记中的判断语句了,方便,并且代码简洁。
值得注意的是如果想要把@NotEmpty注解中的提示信息显示到前端,这里用的是全局异常,直接在异常类中添加如下代码:
/**
* 拦截器其他异常
* @param e
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public JSONResult globleException(MethodArgumentNotValidException e){
e.printStackTrace();
List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
List<String> collect = allErrors.stream().map(ObjectError::getDefaultMessage )
.collect(Collectors.toList());
return JSONResult.error("参数校验失败:"+String.join(",",collect));
}
因为@NotEmpty中的提示信息会到后端中显示它在一个数组中,就需要用上面的代码从数组中获取@NotEmpty中的提示信息,就可以显示到前端了;否则它之前返回的错误提示信息不是@NotEmpty中的提示信息