数据校验时开发过程中一个常见的环节,一般来说,为了提高系统运行效率,都会在前端进行数据校验,但是这并不意味着不必在后端做数据校验了,因为用户还是可能在获取数据接口后手动传入非法数据。
普通校验时基础用法,首先在 Spring Boot Web 项目中添加 数据校验相关的依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-validationartifactId>
dependency>
项目创建成功后,查看 LocalValidatorFactoryBean 类的源码,发现默认的 ValidationMessageSource (校验出错时的提示文件)是 resources 目录下的 ValidationMessage.properties 文件,创建该文件。
user.name.size=用户名长度介于5到10个字符之间
user.address.notnull=用户地址不能为空
user.age.size=年龄输入不正确
user.email.notnull=邮箱不能为空
user.email.pattern=邮箱格式不正确
创建 User 类,配置数据校验
public class User {
private Integer id;
@Size(min = 5,max = 10,message = "{user.name.size}")
private String name;
@NotNull(message = "{user.address.notnull}")
private String address;
@DecimalMin(value = "1",message = "{user.age.size}")
@DecimalMax(value = "200",message = "{user.age.size}")
private Integer age;
@Email(message = "{user.email.pattern}")
@NotNull(message = "{user.email.notnull}")
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
代码解释:
接着创建 Controller
@RestController
public class UserController {
@PostMapping("/user")
public List<String> addUser(@Validated User user, BindingResult result){
List<String> errors = new ArrayList<>();
if (result.hasErrors()){
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError error : allErrors){
errors.add(error.getDefaultMessage());
}
}
return errors;
}
}
代码解释:
启动项目,使用 Postman 直接访问 “http://localhost:8080/user”接口

出现乱码情况,添加配置类,覆盖其中的 getValidator 方法
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected Validator getValidator() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
// 读取配置文件的编码格式
messageSource.setDefaultEncoding("utf-8");
// 缓存时间,-1表示不过期
messageSource.setCacheMillis(-1);
// 配置文件前缀名,设置为Messages,那你的配置文件必须以Messages.properties/Message_en.properties...
messageSource.setBasename("ValidationMessages");
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory();
factoryBean.setMessageInterpolator(interpolatorFactory.getObject());
factoryBean.setValidationMessageSource(messageSource);
return factoryBean;
}
}
重启项目,再次访问

如果传入用户地址、一个非法邮箱地址、一个格式不正确的用户名,结果如下

有的时候开发者在某一个实体类中定义了很多校验规则,但是在某一次业务处理中,并不需要这么多校验规则,此时就可以使用分组校验。
首先创建两个分组接口
public interface ValidationGroup1 {
}
public interface ValidationGroup2 {
}
然后在实体类中添加分组信息
public class User {
private Integer id;
@Size(min = 5,max = 10,message = "{user.name.size}",groups = ValidationGroup1.class)
private String name;
@NotNull(message = "{user.address.notnull}",groups = ValidationGroup2.class)
private String address;
@DecimalMin(value = "1",message = "{user.age.size}")
@DecimalMax(value = "200",message = "{user.age.size}")
private Integer age;
@Email(message = "{user.email.pattern}")
@NotNull(message = "{user.email.notnull}",groups = {ValidationGroup1.class,ValidationGroup2.class})
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
这次在部分注解中添加了 groups 属性,表示该校验规则所属的分组,接下来在 @Validated 注解中指定校验分组
@RestController
public class UserController {
@PostMapping("/user")
public List<String> addUser(@Validated(ValidationGroup2.class) User user, BindingResult result){
List<String> errors = new ArrayList<>();
if (result.hasErrors()){
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError error : allErrors){
errors.add(error.getDefaultMessage());
}
}
return errors;
}
}
@Validated(ValidationGroup2.class 表示这里的校验使用 ValidationGroup2 分组的校验规则,即只校验邮箱地址是否为空、用户地址是否为空。
输入错误的邮箱地址、错误的用户名,测试结果如下

实际上的校验注解布置前面提到的几个,完整的校验注解如下