SpringBoot Validator数据校验
共 5384字,需浏览 11分钟
·
2021-12-15 22:25
什么是数据校验?
Spring-boot-starter-validation可以用来校验SpringMVC的入参,也就是可以用来校验参数的合理性。
在数据校验中,如果传递的参数不满足要求,或者未传递参数,后台服务接口拒绝请求,并返回400错误,一个糟糕的请求。
这就很方便的处理了数据校验。
提示:
Spring Boot 的Validator数据校验实际上使用的是Hibrenate的Validator数据校验。
测试代码:
/**
* 控制层Controller
* @Author 黄柏茗
* @Date 2021-12-14
*/
@RestController
@RequestMapping("/test")
public class UserController {
@RequestMapping("/saveUser")
public User saveUser( User user) {
//保存信息
System.out.println("用户信息保存成功!");
return user;
}
}
测试访问:(未输入数据)
使用validation数据校验
校验入参的合理性,和合法性。
1.引入依赖:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-validationartifactId>
dependency>
2.在实体属性上添加校验注解
public class User {
private int id;
@NotBlank(message = "用户名不能为空")
private String userName;
@NotBlank(message = "密码不能为空")
@Length(min = 2,max = 20,message = "密码长度在2-20之间")
private String password;
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不合理")
private String email;
}
被加上注解的属性,会在MVC入参时进行数据校验,如不合理,则返回400错误,并在后台输出错误信息。
3.在方法上加上 @Valid 或者 @Validated 注解:
测试:(未输入数据)
后台输出
访问:(输入合法参数)
localhost:8080/test/saveUser?userName=黄柏茗&password=1234&email=4533@qq.com
简单的使用过程就是这了。
validation常用校验注解
1.JSR提供的校验注解:
@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(regex=,flag=) 被注释的元素必须符合指定的正则表达式
2.Hibernate Validation提供的校验注解
@NotBlank(message=) 验证字符串非null,且trim后长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
举个例子奥
1. 姓名长度必须在2-20之间
@NotNull(message = "姓名不能为空")
@Size(min = 2, max = 20, message = "姓名长度必须在1-20之间")
private String name;
2. 年龄需要在10-30之间
@Min(value = 10, message = "年龄必须大于10")
@Max(value = 150, message = "年龄必须小于30")
private Integer age;
3. 邮箱格式校验
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不合理")
private String email;
4. 自定义邮箱正则表达式
@Email(regexp = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$",message = "邮箱格式不合理")
private String email;
5.手机号格式校验
@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
@NotBlank(message = "手机号码不能为空")
private String phone;
进阶使用
1.有无 @NotBlank的区别
代码一:
private String password;
代码二:
private String password
这两段代码的区别是属性上是否有 @NotBlank 注解。
结果也是有区别的
访问:
//注意,没输入密码参数奥
localhost:8080/test/saveUser?userName=黄柏茗&email=4533@qq.com
代码一正常访问。
代码二提示密码不能为空。
也就是代码一:入参password可以不带,会进行长度校验,可以正常访问。
代码二:入参必须填写,填写的规则必须满足要求。
简单理解:
没有注解,可以正常访问,有注解就要传递入参。
2.单个参数校验
在方法中如果是单个参数,也可以校验。
需要在类上添加 @Validated 注解,否则不会生效。
也成参数平铺。
import com.hbm.example.boottestvalidation.pojo.User;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 控制层Controller
*
* @Author 黄柏茗
* @Date 2021-12-14
*/
@RestController
@RequestMapping("/test")
@Validated //用于支持方法的单参数校验
public class UserController {
@RequestMapping("/test2")
public String test2(@NotBlank(message = "需要参数name") String name) {
//保存信息
System.out.println("你输入的是:"+name);
return name;
}
}
当参数平铺到方法入参中时,在这种情况下,必须在Controller类上标注 @Validated 注解,并在入参上声明约束注解(如@Min等,你需要的校验注解)。
3.校验模式
默认的校验模式为普通模式,一次性返回了所有验证不通过的集合(控制台打印)。
通常按顺序验证到第一个字段不符合验证要求时,就可以直接拒绝请求了。
Hibernate Validateor有以下2种验证模式:
普通模式(默认)
会校验完所有的属性,然后返回所有的验证失败的信息。
快速失败返回模式
只要一个验证失败,则返回验证失败,拒绝请求,
配置快速返回失败模式:
@Bean
public LocalValidatorFactoryBean getValidatorFactory(){
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.getValidationPropertyMap().put("hibernate.validator.fail_fast","true");
System.out.println("已配置快速失败返回模式");
return localValidatorFactoryBean;
}
此方法交给Ioc容器进行管理即可,自动开启快速返回模式。
只要传入的一个参数不合理,就直接
在验证未通过验证后,会直接返回400错误,一个坏的请求。
4.异常独自处理
我们需要在方法里定义 BindingResult 对象,该对象用于检测该方法内是否发生异常,如果发生异常,可以在里面处理异常,保证服务正常合理。
也就是说,如果发生异常,不想直接抛出,可以添加 BindingResult 参数。
/**
* 测试保存用户
* @param user 入参对象
* @param bindingResult 绑定结果对象(可用判断异常是否出现)
* @return
*/
@RequestMapping("/saveUser")
public User saveUser(@Validated User user, BindingResult bindingResult) {
//如果发生异常,则可以独自处理
if (bindingResult.hasErrors()) {
System.err.println("有异常信息");
for (ObjectError error : bindingResult.getAllErrors()) {
//打印异常信息
System.out.println(error.getDefaultMessage());
}
//在此处可以处理异常,随意发挥,在这里我返回null
return null;
}
//保存信息,进入业务代码
System.out.println("业务完成,用户信息保存成功!");
return user;
}
如果传入参数有异常,就在这里处理,没有异常,则进入业务代码。
提示:
Springboot版本小于2.3.x,自动包含spring-boot-starter-web会自动传入hibernate-validator依赖。
Springboot版本大于2.3.x,需要手动导入依赖。
总结:
校验MVC的入参是否合理还是挺方便的,可以减少大量的 if 判断。
配合使用独自处理异常,还是很OK的。