在Springboot中使用自定义注解进行controller层的数据校验

在Springboot中使用自定义注解进行controller层的数据校验

利用Springboot开发后端项目时,常常需要对前端传递的参数进行校验,查看数据的格式是否正确等,多数情况下都会选择重新定义方法进行校验或者自定义注解进行校验,本文讲解利用自定义注解进行校验。

需要引入自定义注解相关的数据包:

 <dependency>
     <groupId>javax.validation</groupId>
     <artifactId>validation-api</artifactId>
     <version>2.0.1.Final</version>
 </dependency>

1、首先我们先自定义一个注解进行手机号码的验证

/**
 * 校验手机号注解
 * @author wsl
 * @version 1.0
 * @date 2021/10/15 20:51
 */
@Documented
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = IsPhoneValidator.class)
public @interface IsPhone {
    boolean required() default true;
    String message() default "手机号格式不正确";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

首先这里我定义了一个注解命名为IsPhone

首先说明其中各个方法的作用:

  • required()这里为布尔类型,即表示被此注解标记的参数必须含有的,不能为空,默认是true,即含有的。
  • message()的作用是如果被你这个注解标记的参数出现了不满足条件出现了格式错误,则可以由系统定义的全局异常捕获到错误信息,将你的message返回的信息作为错误信息捕获。
  • 下面两个方法均为固定写法。

下面我们来依次说明上面各个注解的作用:

  1. @Documented:为了在生成javadoc的时候就会把@Documented注解给显示出来。

  2. @Target:为了限定你自己在这开发的自定义注解的作用范围,在这里也就是限定我的@Isphone的使用范围。作用范围取决于ELementType。ElementType的用法

    取值注解使用范围
    METHOD可用于方法上
    TYPE可用于类或者接口上
    ANNOTATION_TYPE可用于注解类型上(被@interface修饰的类型)
    CONSTRUCTOR可用于构造方法上
    FIELD可用于域上
    LOCAL_VARIABLE可用于局部变量上
    PACKAGE用于记录java文件的package信息
    PARAMETER可用于参数上
  3. @Retention:定义被它所注解的注解保留多久,一共有三种策略,定义在RetentionPolicy枚举中:

    source:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略

    class:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期

    runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在

    这3个生命周期分别对应于:Java源文件(.java文件) —> .class文件 —> 内存中的字节码。前者能作用的地方后者也一定能作用。

  4. @Constrain:既然我们自定义了注解去进行参数校验,那么参数校验的逻辑在哪呢?就是这个@Constrain在帮我们进行逻辑验证。

    validatedBy指定了我们进行参数逻辑验证的类,下面我们来看看这个类:

    /**
     * @author wsl
     * @version 1.0
     * @date 2021/10/15 20:51
     */
    public class IsPhoneValidator implements ConstraintValidator<IsPhone,Object> {
    
        private boolean required;
    
        @Override
        //类一旦被加载即调用此方法
        public void initialize(IsPhone isphone) {
            System.out.println("进入初始化");
            required = isphone.required();
        }
    
        @Override
        //这里的o即为传递的参数手机号码mobile
        public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
            //电话号码转换成字符串类型
            String mobile = "" + o;
            System.out.println(mobile);
            if (!"".equals(mobile) && required) {
                String regexp = "^[1][3,4,5,6,7,8,9]\\d{9}$";
                return Pattern.matches(regexp, mobile);
            }
            return true;
        }
    }
    

    可以看到这个类实现了ConstraintValidator<IsPhone,Object>这个接口,这样这个类才可以拿到传经来的参数。并且实现了接口中的两个方法。其中类一旦被加载即调用方法initialize,参数进行逻辑校验则在isValid方法中。返回true则表示参数校验成功。

    注意:initialize方法只会在注解被第一次调用的时候才会进行

2、使用此注解

首先,最重要的一点,在你将受用此注解的上面加入@Validated注解,必须加入,否则注解无法生效!!!如下:

@RestController
@RequestMapping("/sms")
@Validated //必须加这个配置,自定义注解才能生效!!!
public class SmsController extends BaseController{
    
    @PostMapping("/send")
    public ApiResponse sendSmsCode(@IsPhone @RequestParam long mobile){
        System.out.println(mobile);
        return createResponse();
    }

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N7X5XupG-1634366220789)(C:\Users\24386\AppData\Roaming\Typora\typora-user-images\image-20211016143444986.png)
在这里插入图片描述

现在我们来调用这个接口,可以看到以下的输出:
在这里插入图片描述

成功进行了自定义注解进行参数校验。

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值