spring-boot-starter-validation
是 Spring Boot 中用于支持数据验证的模块。它建立在 Java Validation API(JSR-380)之上,提供了一种方便的方式来验证应用程序中的数据。以下是使用 spring-boot-starter-validation
的基本方法:
快速入门
添加依赖:
在你的 Spring Boot 项目的 pom.xml
文件中,添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
如果你使用 Gradle,可以在 build.gradle
文件中添加:
implementation 'org.springframework.boot:spring-boot-starter-validation'
创建验证规则:
在需要进行数据验证的类中,使用 Java Validation API 中的注解标记字段,以定义验证规则。例如,使用 @NotBlank
来确保字段不为空:
public class MyRequest {
@NotBlank
private String name;
/**
* 1.@NotNull:不能为null,但可以为empty(""," "," ")
* 2.@NotEmpty:不能为null,而且长度必须大于0 (" "," ")
* 3.@NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度必须大于0("test") 即:必须有实际字符
* 复制代码
*/
@NotBlank(message="用户名不能为空")
private String userName;
@NotBlank(message="年龄不能为空")
@Pattern(regexp="^[0-9]{1,2}$",message="年龄不正确")
private String age;
@AssertFalse(message = "必须为false")
private Boolean isFalse;
/**
* 如果是空,则不校验,如果不为空,则校验
*/
@Pattern(regexp="^\\d{4}(-)(1[0-2]|0?\\d)\\1([0-2]\\d|\\d|30|31)$",message="出生日期格式不正确")
private String birthday;
@Pattern(regexp = "^[M|F|U|m|f|u]{1}$")
private String gender;
@Pattern(regexp = "^(MS)?(MR)?(PRO)?(MRS)?(DOC)?$")
private String civility;
@Size(min = 1, message = "field names can't be empty")
private List<String> names = new ArrayList();
// Other fields and methods...
}
这只是一个简单的例子,Java Validation API 提供了许多其他注解,如 @NotNull
、@Min
、@Max
、@Email
等,以满足各种验证需求。
在控制器中使用验证:
在需要验证输入数据的地方,通常是在 Spring MVC 的控制器中,使用 @Valid
注解来启用验证:
@RestController
public class MyController {
@PostMapping("/submit")
public ResponseEntity<String> submit(@Valid @RequestBody MyRequest request) {
// Process the validated request
return ResponseEntity.ok("Request is valid");
}
}
在上面的例子中,@Valid
注解用于告诉 Spring Boot 对 MyRequest
对象进行验证。如果验证失败,将会抛出 MethodArgumentNotValidException
异常。
处理验证错误:
若要处理验证错误,可以使用 BindingResult
对象。修改控制器方法以接受 BindingResult
参数,并检查是否有错误:
@RestController
public class MyController {
@PostMapping("/submit")
public ResponseEntity<String> submit(@Valid @RequestBody MyRequest request, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
// Handle validation errors
return ResponseEntity.badRequest().body("Validation errors");
}
// Process the validated request
return ResponseEntity.ok("Request is valid");
}
}
这就是使用 spring-boot-starter-validation
的基本步骤。通过这种方式,你可以方便地在 Spring Boot 应用程序中进行数据验证,确保输入数据的合法性。
分组校验
在使用 Spring Boot Validation 进行分组校验时,你可以使用 Validation API 提供的 @GroupSequence
注解来定义校验顺序。下面是一个简单的示例,演示如何在 Spring Boot 中实现分组校验。
首先,假设你有一个包含分组信息的 Java Bean 类:
import javax.validation.GroupSequence;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class MyRequest {
// 定义分组
public interface FirstGroup {}
public interface SecondGroup {}
// 定义分组顺序
@GroupSequence({FirstGroup.class, SecondGroup.class})
public interface AllGroups {}
// 分组校验示例
@NotNull(message = "ID不能为空", groups = FirstGroup.class)
private Long id;
@NotBlank(message = "姓名不能为空", groups = SecondGroup.class)
private String name;
@NotNull(groups = {FirstGroup.class, SecondGroup.class}, message = "密码不能为空")
private String password;
// 省略其他字段和方法
}
在上述示例中,我们定义了两个分组 FirstGroup
和 SecondGroup
,然后使用 @GroupSequence
注解定义了它们的顺序。接着,在字段上使用 @NotNull
和 @NotBlank
注解,并通过 groups
属性指定了校验时所属的分组。
接下来,在你的控制器或服务中,使用 @Validated
注解来指定使用哪个分组进行校验:
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.RestController;
@RestController
@Validated
public class MyController {
@PostMapping("/submit")
public String submit(@Validated(MyRequest.FirstGroup.class) @RequestBody MyRequest request) {
// 处理请求
return "Request is valid";
}
@PostMapping("/update")
public String update(@Validated(MyRequest.SecondGroup.class) @RequestBody MyRequest request) {
// 处理请求
return "Request is valid";
}
}
在上述示例中,@Validated
注解用于标记控制器,然后在方法参数上使用 @Validated
注解来指定使用哪个分组进行校验。在 /submit
接口中使用了 FirstGroup
进行校验,而在 /update
接口中使用了 SecondGroup
进行校验。
这样,你就可以实现基于分组的校验。请注意,分组的顺序是在 @GroupSequence
注解中定义的。
@Validated与@Valid 的区别
@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制,这个网上也有资料,不详述。
@Valid:作为标准JSR-303规范,还没有吸收分组的功能。
常用注解说明
在 Spring Boot 中,用于数据验证的常用注解是来自 Java Validation API(JSR-380)的注解。以下是一些常用的注解:
- 通用注解:
-
@NotNull
: 验证注解的元素值不是 null。 -
@Null
: 验证注解的元素值是 null。 -
@AssertTrue
: 验证注解的元素值是true
。 -
@AssertFalse
: 验证注解的元素值是false
。 -
@Min(value)
: 验证注解的元素值大于等于指定的值。 -
@Max(value)
: 验证注解的元素值小于等于指定的值。 -
@Size(max, min)
: 验证注解的元素值的大小在指定的范围内。 -
@Digits(integer, fraction)
: 验证注解的元素值的整数部分和小数部分的数字不超过指定的数值。
- 字符串验证:
-
@NotBlank
: 验证注解的元素值不为空(不为 null、去掉前后空格后长度大于0)。 -
@NotEmpty
: 验证注解的元素值不为 null 且不为空。 -
@Email
: 验证注解的元素值是一个有效的电子邮件地址。
- 数值验证:
-
@Positive
: 验证注解的元素值是正数。 -
@PositiveOrZero
: 验证注解的元素值是非负数。 -
@Negative
: 验证注解的元素值是负数。 -
@NegativeOrZero
: 验证注解的元素值是非正数。
- 日期和时间验证:
-
@Past
: 验证注解的元素值是过去的日期或时间。 -
@PastOrPresent
: 验证注解的元素值是过去或当前的日期或时间。 -
@Future
: 验证注解的元素值是将来的日期或时间。 -
@FutureOrPresent
: 验证注解的元素值是将来或当前的日期或时间。
- 自定义注解:
- 你还可以创建自定义的注解,通过实现
ConstraintValidator
接口来定义自己的验证逻辑,并使用@Constraint
注解进行声明。
这些注解可以通过在 Java Bean 的字段上使用来进行数据验证。在 Spring Boot 中,通常与 @Valid
或 @Validated
一起使用,以触发验证。在上述提到的示例中,已经展示了一些常用注解的使用方式。
示例:
以下是常用定义校验的注解及其使用示例:
-
@NotNull
:被注解的元素必须不为null。例如:
public class User {
@NotNull(message = "姓名不能为空")
private String name;
// ...其他字段...
}
-
@NotEmpty
:被注释的对象必须不为空(数据:String,Collection,Map,arrays)。例如:
public class User {
@NotEmpty(message = "角色列表不能为空")
private List<Role> roles;
// ...其他字段...
}
-
@NotBlank
:CharSequence子类型,验证注解的元素值不为空(包括不为null或去除首位空格后长度为0)。例如:
public class User {
@NotBlank(message = "手机号码不能为空")
private String phoneNumber;
// ...其他字段...
}
-
@Min
:验证数字是否小于等于指定的最小值。例如:
public class User {
@Min(value = 18, message = "年龄不能低于18岁")
private int age;
// ...其他字段...
}
-
@Max
:验证数字是否大于等于指定的最大值。例如:
public class User {
@Max(value = 60, message = "年龄不能超过60岁")
private int age;
// ...其他字段...
}
-
@Pattern
:用于校验字符串是否符合指定的正则表达式。例如:
public class User {
@Pattern(regexp = "^\\d{6}$", message = "身份证号码格式不正确")
private String idCardNumber;
// ...其他字段...
}
-
@Size
:用于限制字符序列(如String、Collection、Map等)的长度,支持min和max属性。例如:
public class User {
@Size(min = 6, max = 18, message = "密码长度必须在6-18之间")
private String password;
// ...其他字段...
}
-
@Email
:用于校验邮箱地址。例如:
public class User {
@Email(message = "请输入正确的邮箱地址")
private String email;
// ...其他字段...
}
-
@Past
:用于判断日期是否在过去。例如:
public class User {
@Past(message = "生日不能晚于现在")
private Date birthday;
// ...其他字段...
}
-
@Future
:用于判断日期是否在未来。例如:
public class User {
@Future(message = "截止日期必须在未来")
private Date deadline;
// ...其他字段...
}
-
@DecimalMax
:验证数字是否小于等于指定的最大值。例如:
public class User {
@DecimalMax(value = "100.00", message = "金额不能超过100元")
private double amount;
// ...其他字段...
}
-
@DecimalMin
:验证数字是否大于等于指定的最小值。例如:
public class User {
@DecimalMin(value = "1.00", message = "价格不能低于1元")
private double price;
// ...其他字段...
}
以上都是常见的数据校验注解,使用这些注解可以让我们的应用程序具有更强的健壮性,避免非法数据的输入。