SpringBoot Validator数据校验

Java猫

共 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的区别


代码一:

@Length(min = 6,max = 20,message = "密码长度在6-20之间")private String password;


代码二:

@NotBlank(message = "密码不能为空")@Length(min = 6,max = 20,message = "密码长度在6-20之间")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种验证模式:


  1. 普通模式(默认)

    会校验完所有的属性,然后返回所有的验证失败的信息。

  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的。

浏览 85
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报