SpringMVC,SpringBoot快速验证参数是否完整 基于@Valid注解

前言

在接口开发中,经常是需要对传入参数完整性进行验证的,或者对手机号格式进行验证等,而一般不了解@Valid注解之前,都是通过自己封装方法来验证,都是一堆if else集合,这样判断对于代码结构很不友好,开发效率也不高,使用@Valid注解可以快速的对参数进行验证,并且可以通过抓取全局异常,从而实现统一返回

引用

@Valid是使用hibernate validation的时候使用,其中java的jsr303声明了这类接口,hibernate-validator对其进行了实现

在进行maven整合时,需要引入的依赖

COPY
1
2
3
4
5
6
 <dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>

一般情况下早已被其他框架引入了,只是在不存在的时候需要进行引用一下,@Valid只是验证参数是否符合要求,但是具体参数需要符合什么要求,还是需要其他注解来标志验证规则

验证规则标签

@Null       验证对象是否为null

@NotNull    验证对象是否不为null, 无法查检长度为0的字符串

@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.

@NotEmpty 检查约束元素是否为NULL或者是EMPTY.

@AssertTrue     验证 Boolean 对象是否为 true

@AssertFalse    验证 Boolean 对象是否为 false

@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内

@Length(min=, max=) 验证字符串长度是否在给定的范围之内

@Past           验证 Date 和 Calendar 对象是否在当前时间之前

@Future     验证 Date 和 Calendar 对象是否在当前时间之后

@Pattern    验证 String 对象是否符合正则表达式的规则

@Min            验证 Number 和 String 对象是否大等于指定的值

@Max            验证 Number 和 String 对象是否小等于指定的值

@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度

@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度

@Digits     验证 Number 和 String 的构成是否合法

@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。

@Range(min=, max=) 验证元素是否在合适的范围内

@Email  验证是否是邮件地址,如果为null,不进行验证,算通过验证。

使用

在需要验证的类属性上添加相应的注解,如:

COPY
1
2
3
4
5
6
7
8
9
10
11
12
import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;

@Data
public class LoginVO {

@NotBlank
private String username;
@NotBlank
private String password;
}

在SpringMVC控制层中使用@Valid注解进行验证,并判断是否有异常

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
@PostMapping("login")
public String login(@Valid LoginVO vo, Errors errors){
if (errors.hasErrors()) {
List<FieldError> list = errors.getFieldErrors();
StringBuffer sb = new StringBuffer("参数:");
for(FieldError error : list){
sb.append(error.getField()).append(",");
}
sb.append("不符合要求");
return sb.toString();
}
return "验证通过";
}

当然上面Controller层的代码非常容易重复,毕竟差不多的方法都需要验证参数,所以为了方面和简洁代码,可以通过抓取全局异常的方式返回提示信息

全局异常处理

通过配置全局异常处理方法,抓取BindException,返回异常提示信息

COPY
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
27
28
29
import com.wxkingbos.patrol.model.WebResult;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* 全局异常处理器
* Created by Raye on 2019-04-15
*/
@ControllerAdvice
public class ExceptionControllerAdvice {

@ExceptionHandler(BindException.class)
@ResponseBody
public String bindExceptionHandler(BindException ex){
if(ex.hasErrors()){
List<FieldError> list = ex.getFieldErrors();
StringBuffer sb = new StringBuffer("参数:");
for(FieldError error : list){
sb.append(error.getField()).append(",");
}
sb.append("不符合要求");
return sb.toString();
}
return ex.getMessage();
}
}

同理,也可以采用此方法抓取其他全局异常,进行异常日志捕捉获取其他异常提示,另外以上全局异常配置只有在Springboot项目上运行过,因为现在项目差不多都是基于Springboot构建的了,所以也没有在非Springboot上面测试过可行性

Authorship: 作者
Article Link: https://raye.wang/2019/05/07/SpringMVC-SpringBoot%E5%BF%AB%E9%80%9F%E9%AA%8C%E8%AF%81%E5%8F%82%E6%95%B0%E6%98%AF%E5%90%A6%E5%AE%8C%E6%95%B4-%E5%9F%BA%E4%BA%8E-Valid%E6%B3%A8%E8%A7%A3/
Copyright: All posts on this blog are licensed under the CC BY-NC-SA 4.0 license unless otherwise stated. Please cite Raye Blog !