您的位置:首页 > 编程语言 > Java开发

使用spring validation + jsr303 对复杂对象入参进行校验

2019-06-16 16:15 411 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/ahao_henrry/article/details/92403008
[code]    在写rest 接口的时候,复杂对象的参数校验真是比较头疼的问题,以前校验都是一个个写if 判断,当然这无疑工作量巨大,我是那种
工具依赖程度比较重的人,有可以让事情变得简单的东西肯定会去尝试下的,所以google 了一下复杂参数的校验,还真是有通过spring +
jsr303 规范来做校验的方法,在这里做一下简单的总结。
[code]首先通过IDEA 的Spring Initializr 创建一个spring boot 工程(因为方便快速),此工程源码在github,然后将pom.xml 中的依赖修改下
[code]<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
</dependencies>
[code]    分别创建一个UserVO、CarVO、DogVO 以及一个用于传输返回数据的ResultDTO ,再给需要校验的字段分别加上校验注解,各种注解
的含义会在后面给出,内容如下(省略setter 和getter),该user 除了普通属性名字和年龄外还拥有一条狗和很多辆车。注意在cars
和dog 属性上的@Valid 注解,该注解代表该对象属性也要被校验,如果不加该注解的话那么即使在该对象属性里加了对应的校验注解也不会
被校验。
[code]/**
* @author ahao
* @since 2019/6/12 20:12
**/
public class UserVO {
private String name;

@NotNull(message = "你多少岁啦")
private Integer age;

@Valid
@NotEmpty(message = "你至少得要有一辆车啊")
@Size(min = 1, message = "你至少得要有一辆车啊")
private List<CarVO> cars;

@Valid
@NotNull(message = "你得要有只狗啊")
private DogVO dog;
}
[code]/**
* @author ahao
* @since 2019/6/12 20:14
**/
public class CarVO {
@NotEmpty(message = "你的车什么颜色啊")
private String carColor;

private String carWeight;
}
[code]/**
* @author ahao
* @since 2019/6/12 20:15
**/
public class DogVO {
@NotEmpty(message = "你的狗叫什么名字啊")
private String dogName;

private String dogColor;
}
[code]/**
* @author ahao
* @since 2019/6/12 22:03
**/
public class ResultDTO {
private String code;

private String message;

private Object data;

public ResultDTO(String code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
}
[code]然后创建一个新建一个类来创建rest 接口,内容如下
[code]package com.ahao.paramvalidation.ctrl;

import com.ahao.paramvalidation.to.ResultDTO;
import com.ahao.paramvalidation.vo.UserVO;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @author ahao
* @since 2019/6/12 20:06
**/
@RestController
@RequestMapping("/param")
public class ParamsCtrl {
private static final Logger LOGGER = LoggerFactory.getLogger(ParamsCtrl.class);

@PostMapping("/post")
public ResultDTO paramsValidation(@RequestBody @Validated UserVO userVO, BindingResult bindingResult) {
LOGGER.info("param is : {}", JSONObject.toJSONString(userVO));
if (bindingResult.hasErrors()) {
String err = bindingResult.getFieldError().getDefaultMessage();
return new ResultDTO("400", "fail", err);
}
return new ResultDTO("200", "success", "(●ˇ∀ˇ●)");
}
}

创建好的工程结构就像下图一样

[code]    这样一创建下来的话基本上就完工了,@Validation 注解必须要加上,因为它代表该参数要被校验。bindingResult 要紧跟在被校
验的对象后面,用来返回错误信息,当有参数校验不合格的时候可以通过bindingResult 来判断。
接下来启动工程开始做测试,这里通过HTTPie 作为工具请求该接口。首先创建一个完整参数的jso
3ff7
n,得到结果为

[code]上面的框为入参,下面的框为出参。
[code]然后我们把他其中一辆车颜色去掉,继续测试得到结果为

[code]然后我们把他的车开走,继续测试得到结果为

[code]然后我们把他车还回去,把他的的狗给牵走,继续测试得到结果为

[code]然后我们把他的狗还回去,把他的年龄抹去,继续测试得到结果为

[code]好了,到这里复杂参数的校验基本也清晰了,最后把Javax 里面提供的相关注解及含义放出来把,这些注解已经能够满足绝大多数的参数校验,
看javax 的源码,主要有以下相关注解
@AssertFalse 被注解的元素必须是false
@AssertTrue 被注解的元素必须是true
@DecimalMax 被注解的元素必须是一个数字,值必须小于等于指定的最大值
@DecimalMin 被注解的元素必须是一个数字,值必须大于等于指定的最小值
@Digits 被注解的元素必须是一个数字,值必须在指定的范围
@Email 被注解的元素必须是电子邮箱地址(通过指定正则表达式来匹配邮箱格式)
@Future 被注解的元素必须是一个未来的日期或者时间
@FutureOrPresent 被注解的元素必须是一个当前或者未来的日期或者时间,这个注解还是和@Future 有区别的,比如说当这个注解的匹配是年的话那么就表示当前的整年都可以
@Max 被注解的元素必须是一个数字,值必须小于等于指定的最大值
@Min 被注解的元素必须是一个数字,值必须大于等于指定的最小值
@Negative 被注解的元素必须是严格的负数(比如0不会被校验通过)
@NegativeOrZero 被注解的元素必须是负数和0
@NotBlank 被注解的元素必须不为null 并且至少有一个非空白字符
@NotEmpty 被注解的元素不为null 并且不为empty ,其实null 和empty 是有区别的,比如一个List , 它不等于null , 但是等于[],也就是size 为0
@NotNull 被注解的元素必须不为 null
@Null 被注解的元素必须为 null
@Past 被注解的元素必须是一个过去的日期或者时间
@PastOrPresent 被注解的元素必须是一个过去的或者现在的时间或者日期
@Pattern 被注解的元素必须符合指定的正则表达式
@Positive 被注解的元素必须是一个严格的正数
@PositiveOrZero 被注解的元素必须是正数和0
@Size 被注解的元素的长度必须在指定的范围内
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: