Spring Boot【定制化】~ Validator参数校验

1、简介

  • 数据校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。
  • 使用Validator进行数据校验有利于提高代码可读性、可维护性,还不会导致我们代码业务冗杂。

2、Vaildator常用注解

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=) 被注释的元素必须符合指定的正则表达式

Hibernate Validator 提供的校验注解:

  • @NotBlank(message =) 验证字符串非 null,且长度必须大于 0
  • @Email 被注释的元素必须是电子邮箱地址
  • @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
  • @NotEmpty 被注释的字符串的必须非空
  • @Range(min=,max=,message=) 被注释的元素必须在合适的范围内

3、使用步骤

3.1 使用前需要注意的细节

  • 因为我们是基于 Spring Boot 经行测试,其实只需要到入spring-boot-starter-web 依赖即可(该依赖已经包含了Valiator校验的所有依赖),但是自从Spring Boot 2.3.1之后Validator的依赖已经被从中剔除了,所有想要使用Validator校验需要手动导入Validation依赖。

3.2 导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

3.3 创建测试实体对象

使用方式: 使用检验注解修饰对象属性(按自己需要选择修饰注解)
注意: 这里使用了3个自定义注解后面补充讲解(不懂的可以先注释掉)。

/**
 * 差数校验测试实体对象
 * 
 * @author cms
 * @version 1.0.0.0
 * @Date: 2022/5/22 13:57
 */
@Data
public class LoginBody
{

    @Size(min = 3, max = 11, message = "用户名长度3-11")
    @UsernameCheck //自定义注解
    private String username;

    @Size(min = 3, max = 11, message = "密码长度3-64")
    @PasswordCheck //自定义注解
    private String password;

    /** 自定义注解使用 */
    @PhoneCheck //自定义注解
    private String phoneNumber;

    @Email(message = "邮箱格式有误!")
    private String email;

}

3.4 创建Controller测试类

使用方式:

  • 校验实体对象,使用@Valid注解配置@RequestBody注解开启实体对象属性值校验。
  • 直接在方法上面进行参数校验,在类上使用@Validtor开启controller方法参数校验,然后在需要经行校验的位置自行选择校验注解。
/**
 * @author cms
 * @version 1.0.0.0
 * @Date: 2022/5/21 19:11
 */
@Validated //在该controller开启参数校验
@RestController
public class TestController
{
    /**
     * 使用 @Valid 注解配合 @RequestBody 注解开启实体对象参数校验
     *
     * @param body
     * @return
     */
    @PostMapping("test01")
    public Object test01(@Valid @RequestBody LoginBody body)
    {
        return body;
    }

    /**
     * 直接在方法参数里面使用参数校验
     *
     * @param name 参数
     * @param address 参数
     * @return 结果
     */
    @GetMapping("test02")
    public Object test02(
            @NotBlank(message = "名称不能为空")
            @RequestParam(required = true, value = "name") String name,
            @NotBlank(message = "地址信息不能为空")
            @RequestParam(required = true, value = "address") String address
    )
    {
        return name+": "+address;
    }
    
}

3.5 使用Postmen测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.6 自定义校验注解

作用: 自定义校验规则。

1、自定义手机号码校验注解和校验规则实现类
注解:@PhoneCheck

/**
 * @author cms
 * @version 1.0.0.0
 * @Date: 2022/5/22 14:08
 */
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = PhoneCheckValidator.class) //自定义校验类
@Documented
public @interface PhoneCheck
{

    /** 失败提示信息 */
    String message() default "手机号码格式有误!";

    /** 默认开启手机号码校验 */
    boolean required() default true;

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

实现类:PhoneCheckValidator

/**
 * 自定义手机号码校验规则
 *  1、需要实现 ConstraintValidator 接口,并重写 isValid 方法和 initialize 方法(initialize用到可以重写)。
 *
 * @author cms
 * @version 1.0.0.0
 * @Date: 2022/5/22 14:12
 */
public class PhoneCheckValidator implements ConstraintValidator<PhoneCheck, String>
{

    /** 手机号码是否填写:true(必须填)、false(不用填) */
    private boolean required;

    private final String CHECK_PHONE_NUMBER = "^[1]((3[0-9])|(4[5-9])|(5[0-3,5-9])|([6][5,6])|(7[0-9])|(8[0-9])|(9[1,8,9]))\\d{8}$";

    /**
     * 初始化参数
     * 
     * @param constraintAnnotation 注解
     */
    @Override
    public void initialize(PhoneCheck constraintAnnotation)
    {
        required=constraintAnnotation.required();
    }

    /**
     * 自定义校验规则
     *
     * @param phoneValue 检验的参数
     * @param context 约束验证器上下文
     * @return 校验结果
     */
    @Override
    public boolean isValid(String phoneValue, ConstraintValidatorContext context)
    {
        System.out.println("----------------手机号码校验---------------");

        if (!required)
        {
            return true;
        }

        return phoneValue.matches(CHECK_PHONE_NUMBER);
    }
}

2、自定义用户名校验注解和校验规则实现类
注解:@UsernameCheck

/**
 * @author cms
 * @version 1.0.0.0
 * @Date: 2022/5/22 14:08
 */
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = UsernameCheckValidator.class) //自定义校验类
@Documented
public @interface UsernameCheck
{
    String message() default "用户名格式由数字和26个英文字母组成!";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

实现类:UsernameCheckValidator

/**
 * @author cms
 * @version 1.0.0.0
 * @Date: 2022/5/22 14:12
 */
public class UsernameCheckValidator implements ConstraintValidator<UsernameCheck, String>
{

    //由数字和26个英文字母组成的字符串
    private final String CHECK_USERNAME = "^[A-Za-z0-9]+$";

    @Override
    public boolean isValid(String phoneValue, ConstraintValidatorContext context)
    {
        System.out.println("----------------用户名校验---------------");
        return phoneValue.matches(CHECK_USERNAME);
    }
}

3、自定义密码校验注解和校验规则实现类
注解:@PasswordCheck

/**
 * @author cms
 * @version 1.0.0.0
 * @Date: 2022/5/22 14:08
 */
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = PasswordCheckValidator.class) //自定义校验类
@Documented
public @interface PasswordCheck
{

    String message() default "密码格式由数字和26个英文字母组成!";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

实现类:PasswordCheckValidator

/**
 * @author cms
 * @version 1.0.0.0
 * @Date: 2022/5/22 15:51
 */
public class PasswordCheckValidator implements ConstraintValidator<PasswordCheck, String>
{

   //由数字和26个英文字母组成的字符串
   private final String CHECK_PASSWORD = "^[A-Za-z0-9]+$";

   @Override
   public boolean isValid(String phoneValue, ConstraintValidatorContext context)
   {
      System.out.println("----------------密码校验---------------");
      return phoneValue.matches(CHECK_PASSWORD);
   }
}

4、提示

  • 本测试项目配合了统一结果返回 + 异常拦截一起使用,有兴趣的可以去看看我写的统一结果处理全局异常拦截那篇。
  • 地址:https://blog.csdn.net/qq_41135440/article/details/124901853?spm=1001.2014.3001.5501
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值