说明
本篇主要介绍javax的validation使用,以实际使用出发,后续会再更新,先记录一部分。
简介
javax的validation是基于标准JSR-303规范。JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。JSR-303参考
在SpringBoot中使用方法
- 添加依赖
<!-- Validation 相关依赖 -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
由于SpringBoot中spring-boot-starter-web中引用了hibernate-validator、hibernate-validator又引用了validation-api。因此不需要额外引用validation-api
- 添加约束注解
针对目标Bean,针对不同属性的验证需求,添加不同的约束注解。
public class UserReq implements Serializable {
/**
* 任意类型,验证注解的元素值不是null
*/
@NotNull(message = "userName不能为空")
private String userName;
/**
* BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(存储的是数字)子类型
*
* @Min验证注解的元素值大于等于@Min指定的value值,
* @Max验证注解的元素值小于等于@Max指定的value值
*/
@Min(value = 18, message = "不能小于18岁")
@Max(value = 60, message = "不能大于60岁")
@NotNull
private Integer userAge;
/**
* @Past必须是过去的一个时间
* @Future必须是将来的一个时间
*/
@Past(message = "birthday")
@DateTimeFormat(pattern = "yyy-MM-dd")
@JSONField(format = "yyyy-MM-dd")
private Date birthday;
/**
* 字符串、Collection、Map、数组等。验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小
*/
@Size(min = 1, max = 3, message = "联系人信息不能为空")
private List<ContactInfo> contactInfo;
}
- 开启验证
开启验证的方法有:
验证注解:@Validated或者@Valid (@Validated注解的效果与@Valid是一样的,@Validated是SpringBoot对@Valid注解的封装(@Valid是javax.validation的注解)。而@Validated注解是包含在SpringBoot的spring-boot-web-starter中的。)
@PostMapping("/user")
public String addUser(@RequestBody @Validated UserReq userReq) {
log.info("保存User={}", JSON.toJSONString(userReq));
return "SUCCESS";
}
异常的捕捉。SpringBoot-异常处理
@ExceptionHandler({
MethodArgumentNotValidException.class,
BindException.class,
ValidationException.class,
ConstraintViolationException.class})
@ResponseStatus(HttpStatus.OK)
public BaseResponse tryValidationException(HttpServletRequest request, HandlerMethod handlerMethod, Exception e) {
log.error("参数校验异常,url={},{}#{}", request.getRequestURL(), handlerMethod.getClass(), handlerMethod.getMethod().getName(), e);
BindingResult result = null;
if (e instanceof MethodArgumentNotValidException) {
result = ((MethodArgumentNotValidException) e).getBindingResult();
}
StringBuilder errorMsg = new StringBuilder();
for (ObjectError error : result.getAllErrors()) {
errorMsg.append(error.getDefaultMessage()).append(",");
}
if (errorMsg.length() > 1) {
errorMsg.delete(errorMsg.length() - 1, errorMsg.length());
}
return new BaseResponse().setCode("30").setMessage(errorMsg.toString());
}
约束注解
-
空值校验
@Null:目标值为null。比如,注册时的userId当然是null(即使不为null,系统也不会采用的)。
@NotNull:目标值不为null。比如,登录时的userId当然不为null(当然也可能是通过了外部鉴权,然后内部裸奔)。
@NotEmpty:目标值不为empty。相较于上者,增加了对空值的判断(就是""无法通过@NotEmpty的校验)
@NotBlank:目标值不为blank。相较于上者,增加了对空格的判断(就是空格无法通过@NotBlank校验的) -
范围校验
@Min(value=值):针对数值类型,目标值不能低于该注解设定的值。
@Max(value=值):针对数值类型,目标值不能高于该注解设定的值。
@DecimalMax(value=值):针对数值类型,目标值必须小于该注解设定的值。
@DecimalMin(value=值):针对数值类型,目标值必须大于该注解设定的值。
@Digits(integer=整数位数, fraction=小数位数):针对数值类型,目标值的整数位数必须等于integer参数设定的值,小数位数必须等于fraction参数设定的值。
@Size(min=下限, max=上限):针对:字符串、Collection、Map、数组等,目标集合的元素数量不可以高于max参数,不可以低于min参数。
@Past:针对:java.util.Date,java.util.Calendar;Joda Time类库的日期类型,目标值必须是一个过去的时间。
@Future:针对:java.util.Date,java.util.Calendar;Joda Time类库的日期类型,目标值必须是未来的时间。
@Length(min=下限, max=上限) 针对:CharSequence子类型,验证注解的元素值长度在min和max区间内
@Range(min=最小值, max=最大值),针对:BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子类型和包装类型,验证注解的元素值在最小值和最大值之间。 -
其他校验
@AssertTrue:针对布尔类型,目标值必须为true。
@AssertFalse:针对布尔类型,目标值必须为false。
@Email:针对字符串类型,目标值必须是Email格式。
@URL:针对字符串类型,目标值必须是URL格式。
@Pattern:针对字符串类型,目标值必须通过注解设定的正则表达式
其中:@NotEmpty、@Length、@Range、@Email 是Hibernate Validator附加的。
网友评论