背景
Spring Validation验证框架对参数的验证机制提供了@Validated(Spring’s JSR-303 规范,是标准 JSR-303 的一个变种), javax 提供了@Valid(标准 JSR-303 规范),配合BindingResult可以直接提供参数验证结果。
@Validated和@Valid在基本验证功能的区别:
@Validated
分组:提供分组功能,可在入参验证时,根据不同的分组采用不同的验证机制。
可注解位置 :可以用在类型、方法和方法参数上,但是不能用在成员属性上。
嵌套验证:用在方法入参上无法单独提供嵌套验证功能,不能用在成员属性上,也无法提供框架进行嵌套验证,能配合嵌套验证注解@Valid进行嵌套验证。
@Valid
分组:无分组功能
可注解位置:可以用在方法、构造函数、方法参数和成员属性上(两者是否能用于成员属性上直接影响能否提供嵌套验证的功能)
嵌套验证:用在方法入参上无法单独提供嵌套验证功能,能够用在成员属性上,提示验证框架进行嵌套验证,能配合嵌套验证注解@Valid进行嵌套验证。
代码案例
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
接收参数类:
import lombok.Data;
import org. hibernate .validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.*;
@Data
public class StringParam {
@Null(message = "必须为null")
private String v1;
@NotNull(message = "不能为null")
private String v2;
@NotBlank(message = "只用于String,不能为null,且 trim ()之后size>0")
private String v3;
@Length(min = 1, max = 5, message = "长度范围")
private String v4;
@Email(message = "邮箱格式不正确")
private String v5;
@Digits(message = "限制必须为一个小数,且整数部分的位数不能超过 integer ,小数部分的位数不能超过fraction", integer = 10, fraction = 2)
private String v6;
@Range(message = "元素的大小范围", min = 10, max = 100)
private String v7;
@NotEmpty(message = "不能为null,长度大于0")
private String v8;
@Pattern(regexp = "^[a-zA-Z0-9]+$", message = "正则表达式")
private String v9;
}
import lombok.Data;
import javax.validation.constraints.*;
@Data
public class number Param {
@Min(value = 100L, message = "int,必须为数字,其值大于或等于指定的最小值")
private int v1;
@Max(value = 100L, message = "int,必须为数字,其值小于或等于指定的最大值")
private int v2;
@Min(value = 100L, message = "double,必须为数字,其值大于或等于指定的最小值")
private double v3;
@Max(value = 100L, message = "double,必须为数字,其值小于或等于指定的最大值")
private double v4;
}
import lombok.Data;
import javax.validation.constraints.AssertFalse;
import javax.validation.constraints.AssertTrue;
@Data
public class Boolean Param {
@AssertTrue(message = "v1, 只能为true")
private boolean v1;
@AssertFalse(message = "v2, 只能为false")
private boolean v2;
}
import com.fasterxml.jackson. annotation .JsonFormat;
import lombok.Data;
import javax.validation.constraints.Future;
import javax.validation.constraints.Past;
import java .util.Date;
@Data
public class DateParam {
// @DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Past(message = "验证注解的元素值(日期类型)比当前时间早")
private Date time1;
// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Future(message = "限制必须是一个将来的日期")
private Date time2;
}
import lombok.Data;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.List;
@Data
public class CollectionParam {
@NotEmpty
@Size(min = 1, max = 11)
private List<String> v1;
@DecimalMin(value = "18", message = "dicimal不能小于18!")
@ Decimal Max(value = "20", message = "dicimal不能大于20!")
private BigDecimal v2;
@NotNull
@Size(min = 4, max = 4)
private List<BigDecimal> v3;
}
Controller 类:
import com.what21.boot.demo01.controller.param.*;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@ Request Mapping("/validation")
@RestController
public class ValidationController {
/**
* @param stringParam
* @param bindingResult
* @return
*/
@RequestMapping(value = "/string", method = {RequestMethod.GET, RequestMethod.POST})
public Object string(@Valid @RequestBody StringParam stringParam, BindingResult bindingResult) {
String result = "成功:" + stringParam;
//如果验证通不过的处理
if (bindingResult.hasErrors()) {
//打印错误
result = bindingResult.getFieldError().getDefaultMessage();
}
return result;
}
/**
* @param numberParam
* @param bindingResult
* @return
*/
@RequestMapping(value = "/number", method = {RequestMethod.GET, RequestMethod.POST})
public Object number(@Valid @RequestBody NumberParam numberParam, BindingResult bindingResult) {
String result = "成功:" + numberParam;
//如果验证通不过的处理
if (bindingResult.hasErrors()) {
//打印错误
result = bindingResult.getFieldError().getDefaultMessage();
}
return result;
}
/**
* @param bool eanParam
* @param bindingResult
* @return
*/
@RequestMapping(value = "/bool", method = {RequestMethod.GET, RequestMethod.POST})
public Object bool(@Valid @RequestBody BooleanParam booleanParam, BindingResult bindingResult) {
String result = "成功:" + booleanParam;
//如果验证通不过的处理
if (bindingResult.hasErrors()) {
//打印错误
result = bindingResult.getFieldError().getDefaultMessage();
}
return result;
}
/**
* @param dateParam
* @param bindingResult
* @return
*/
@RequestMapping(value = "/date", method = {RequestMethod.GET, RequestMethod.POST})
public Object date(@Valid @RequestBody DateParam dateParam, BindingResult bindingResult) {
String result = "成功:" + dateParam;
//如果验证通不过的处理
if (bindingResult.hasErrors()) {
//打印错误
result = bindingResult.getFieldError().getDefaultMessage();
}
return result;
}
/**
* @param collectionParam
* @param bindingResult
* @return
*/
@RequestMapping(value = "/collection", method = {RequestMethod.GET, RequestMethod.POST})
public Object collection(@Validated @RequestBody CollectionParam collectionParam, BindingResult bindingResult) {
String result = "成功:" + collectionParam;
//如果验证通不过的处理
if (bindingResult.hasErrors()) {
//打印错误
result = bindingResult.getFieldError().getDefaultMessage();
}
return result;
}
}
测试
字符串 :
{
"v1": null,
"v2": "",
"v3": "不能为''",
"v4": "1234",
"v5": "abcd@1.com",
"v6": "10.12",
"v7": 12,
"v8": "abcdefgh",
"v9": "xxxxxxx"
}
成功:StringParam(v1=null, v2=, v3=不能为'', v4=1234, v5=abcd@1.com, v6=10.12, v7=12, v8=abcdefgh, v9=xxxxxxx)
数值:
{
"v1": 188.8,
"v2": 88.8,
"v3": 199.9,
"v4": 99.9
}
成功:NumberParam(v1=188, v2=88, v3=199.9, v4=99.9)
Boolean类型:
{
"v1": true,
"v2": false
}
成功:BooleanParam(v1=true, v2=false)
时间类型:
{
"time1": "2021-12-30",
"time2": "2021-12-31 08:56:54"
}
成功:DateParam(time1=Thu Dec 30 00:00:00 CST 2021, time2=Fri Dec 31 08:56:54 CST 2021)
集合类型:
{
"v1": [
"1","2","3"
],
"v2": 19.91,
"v3": [
18.11,18.22,"18.33","18.44"
]
}
成功:CollectionParam(v1=[1, 2, 3], v2=19.91, v3=[18.11, 18.22, 18.33, 18.44])