Java中自定义注解进行参数验证

前言

        Java开发中特别在Web开发中, 经常需要对请求的参数进行验证, 在目前框架中也存在一些常规的参数验证注解, 比如 @NotNull@NotBlank等等, 但是在某些特别的情况下需要自定义参数验证才能满足开发中的需要
        接下来,介绍一下在Java中自定义注解实现参数验证的功能, 主要实现步骤 :

  • 创建一个自定义注解
  • 创建验证器
  • 验证逻辑实现
  • 测试

在开始我们的工作之前, 请确保已经创建了一个SpringBoot项目, 并添加了以下依赖

		<!--Springbot提供的web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--lombok依赖,简化代码-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--验证依赖-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.4.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.logging</groupId>
            <artifactId>jboss-logging</artifactId>
            <version>3.3.0.Final</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml</groupId>
            <artifactId>classmate</artifactId>
            <version>1.3.3</version>
        </dependency>

 

自定义验证注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AnnotationAnally.class)
public @interface  MyAnnotation {
    String message() default "参数效验失败!";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

其中 :

  • @Target 指明这个注解用于在什么地方, 参数是数组类型, 我们一会需要贴字段上,所以只选择了FIELD
  • @Retention 声明此注解的生命周期, 可以有SOURCE(源码,编译会丢弃), CLASS(编译,运行时会丢弃), RUNTIME(运行时期也存在)三种类型, 这里选择了生命周期最长的
  • @Constraint 这是自定义验证注解最重要的, 它用来表示被贴的这个注解是一个验证注解, 参数中指定了验证器
  • message() 指明了验证失败后返回的消息,此方法为@Constraint要求
  • groups()payload() 也为@Constraint要求,可默认为空,详细用途可以查看@Constraint文档
     
创建验证器
public class AnnotationAnally implements ConstraintValidator<MyAnnotation,String> {
    @Override
    public void initialize(MyAnnotation constraint) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return false;
    }
}

其中 :

  • 自定义验证器需要实现 ConstraintValidator 接口, 其中有两个参数,第一个是验证注解,第二个是需要验证的数据类型
  • initialize() 可以在验证开始前调用注解里的方法,从而获取到一些注解里的参数,这里用不到
  • isValid() 就是判断是否合法的地方
     

验证逻辑实现

这里就简单的对手机号码进行验证, 贴上验证器的全部代码

@Slf4j
public class AnnotationAnally implements ConstraintValidator<MyAnnotation, String> {
    //验证手机号码
    private static final Pattern PATTERN = Pattern.compile("^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$");

    /**
     * 初始化方法
     *
     */
    @Override
    public void initialize(MyAnnotation constraint) {
        log.info("开始进行参数验证了...");
    }

    /**
     * 具体的验证逻辑
     *
     * @return true : 验证通过  false : 验证失败
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (StringUtils.hasLength(value)) {
            return PATTERN.matcher(value).matches();
        }
        return false;
    }
}

 

测试

创建一个 User类用来接收参数

@Data
public class User {
    @MyAnnotation
    private String phone;
}

创建一个控制器类用来接收请求, 要使自定义注解生效,还需要在接收参数的地方贴上 @Valid 注解

@RestController
@Slf4j
public class HelloController {
    @PostMapping("/hello")
    public String hello(@Valid @RequestBody User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
        	// 获取验证失败的信息,可在验证注解的message()中设置
            return bindingResult.getAllErrors().get(0).getDefaultMessage();
        }
        log.info("接收到参数:{}", user);
        return "接收成功了!";
    }
}

设置一下SpringBoot内嵌容器的端口号

server:
  port: 8090

启动项目通过Postman 测试一下
先来一个假的手机号
在这里插入图片描述
可以看到返回的结果是我在message()中设置的信息
 
再来一个真的
在这里插入图片描述
可以看到验证通过了…
 
本文到此结束

  • 25
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java,可以通过自定义注解进行数据验证。下面是一个简单的例子: 1. 定义注解 ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String value() default ""; int minLength() default 0; int maxLength() default Integer.MAX_VALUE; String regex() default ""; } ``` 这个注解可以用在类的字段上,可以指定字段的值、最小长度、最大长度和正则表达式。 2. 使用注解 ```java public class User { @MyAnnotation(minLength = 3, maxLength = 10, regex = "[a-zA-Z0-9_]+") private String username; // getter and setter } ``` 在这个例子,我们给User类的username字段加上了MyAnnotation注解,并指定了最小长度为3,最大长度为10,只能包含字母、数字和下划线。 3. 验证数据 ```java public class Validator { public static boolean validate(Object obj) throws IllegalAccessException { Class<?> clazz = obj.getClass(); for (Field field : clazz.getDeclaredFields()) { MyAnnotation annotation = field.getAnnotation(MyAnnotation.class); if (annotation != null) { field.setAccessible(true); String value = (String) field.get(obj); if (value == null || value.length() < annotation.minLength() || value.length() > annotation.maxLength() || !value.matches(annotation.regex())) { return false; } } } return true; } } ``` 这个Validator类可以用来验证任意对象的字段是否符合注解的要求。它通过反射获取对象的所有字段,并检查是否有MyAnnotation注解,然后根据注解的要求验证字段的值。 使用方法: ```java public static void main(String[] args) throws IllegalAccessException { User user = new User(); user.setUsername("abc_123"); boolean isValid = Validator.validate(user); System.out.println(isValid); // true } ``` 在这个例子,我们创建了一个User对象,并将username设置为"abc_123",然后使用Validator类来验证这个对象的所有字段是否符合注解的要求。由于username符合要求,所以验证结果为true。 这样,我们就可以通过自定义注解进行数据验证了。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值