统一校验需求
前端请求后端接口传输参数,在controller
和Service
中都需要校验,只是分工不同。
Contoller
中校验请求参数的合法性,包括:必填项校验,数据格式校验,比如:是否是符合一定的日期格式,等。Service
中校验业务规则相关的内容,比如:课程已经审核通过所以提交失败。
Service
中根据业务规则去校验不方便写成通用代码,Controller
中则可以将校验的代码写成通用代码。
早在JavaEE6规范中就定义了参数校验的规范,它就是JSR-303,它定义了Bean Validation
,即对bean属性进行校验。
SpringBoot
提供了JSR-303
的支持,它就是spring-boot-starter-validation
,它的底层使用Hibernate Validator
,Hibernate Validator
是Bean Validation
的参考实现。
统一校验实现
添加spring-boot-starter-validation
的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
javax.validation.constraints
文件注解如图

如下图所示,直接在类里定义属性的时候添加注解
public class User {
private String userId;
//用户名不为空,使用默认提示
@NotNull
private String username;
@NotEmpty(message = "地址不能为空")
private String address;
//密码进行长度和格式的验证
@Size(min=6, max=18, message="密码长度必须在6 ~ 18字符之间")
@Pattern(regexp="^[a-zA-Z0-9|_]+$", message="密码必须由字母、数字、下划线组成")
private String password;
//手机号码自定义提示,使用正则表达式进行匹配
@Pattern(regexp="^1(3|4|5|7|8|9)\\d{9}$",message="手机号码错误")
private String mobile;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday;
}
规则如下:更多详见文档
Constraint | 详细信息 |
---|---|
@Null | 被注释的元素必须为 null |
@NotNull | 被注释的元素必须不为 null |
@AssertTrue | 被注释的元素必须为 true |
@AssertFalse | 被注释的元素必须为 false |
@Min(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Max(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@DecimalMin(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@DecimalMax(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@Size(max, min) | 被注释的元素的大小必须在指定的范围内 |
@Digits (integer, fraction) | 被注释的元素必须是一个数字,其值必须在可接受的范围内 |
@Past | 被注释的元素必须是一个过去的日期 |
@Future | 被注释的元素必须是一个将来的日期 |
@Pattern(value) | 被注释的元素必须符合指定的正则表达式 |
被注释的元素必须是电子邮箱地址 | |
@Length | 被注释的字符串的大小必须在指定的范围内 |
@NotEmpty | 被注释的字符串的必须非空 |
@Range | 被注释的元素必须在合适的范围内 |
定义好规则后在Controller
中使用还需要开启校验,在Controller
方法中添加@Validated
注解,如下
@PostMapping("/user")
public User createUser(@RequestBody @Validated AddUserDto dto){
return userService.createUser(dto);
}
分组校验
有时同一属性可能有多个不同校验规则
如:创建用户对象时,用户的id为空,而更新用户对象时,id不能为空。
此时需要用到分组校验,同一个属性定义多个校验规则属于不同的分组
比如:添加用户时使用@NULL规则属于insert分组,更新用户信息使用@NotEmpty规则属于update分组,insert和update是分组的名称
可以创建一个类来定义不同分组。如下:
public class ValidationGroups {
public interface Inster{};
public interface Update{};
public interface Delete{};
}
在定义校验规则时指定分组:
@NULL(groups = {ValidationGroups.Inster.class},message = "添加用户时id为空")
@NotEmpty(groups = {ValidationGroups.Update.class},message = "更新用户信息时id不能为空")
private String userId;
在Controller
方法中启动校验规则指定要使用的分组名
@PostMapping("/user")
public User createUser(@RequestBody @Validated({ValidationGroups.Inster.class}) AddUserDto dto){
return userService.createUser(dto);
}
校验规则不满足怎么办?
若javax.validation.constraints包下的校验规则满足不了需求,则需要:
- 手写校验代码
- 自定义校验规则注解