Java中通过方法上注解实现入参校验

21 篇文章 0 订阅

设计思路

要通过注解实现对方法参数的校验,我们将利用Java的反射机制以及Spring AOP(面向切面编程)来实现。这种设计使得参数校验与业务逻辑解耦,提高了代码的可读性和可维护性。

1. 需求分析
  • 自动化校验:不希望在每个方法内部进行详细的参数校验。
  • 灵活性:希望能自定义校验规则。
  • 可重用性:相同的校验逻辑能被多个方法复用。
2. 选择技术
  • Spring AOP:可以在方法执行之前执行参数校验,捕获异常并增强方法行为。
  • Java Bean Validation(JSR 380):提供标准的校验注解(如@NotNull, @Size等),保证参数的合法性。
3. 系统设计
  • 自定义注解:创建一个注解@ValidatedParams,通过它标记需要校验的方法。
  • 切面类(Aspect):实现切面来拦截带有@ValidatedParams注解的方法,对其参数进行校验。
  • 错误处理:在校验失败时抛出适当的异常,以便调用者可以捕获并处理。

 代码实现

1. 自定义注解

创建一个注解@ValidatedParams,它用来标识需要进行参数校验的方法。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidatedParams {
}
2. 创建参数校验切面

使用Spring AOP创建一个切面,来实现参数校验逻辑。

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;

@Aspect
@Component
public class ValidationAspect {

    private final Validator validator;

    public ValidationAspect() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        this.validator = factory.getValidator();
    }

    @Before("@annotation(ValidatedParams)")
    public void validateParams(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();

        for (Object arg : args) {
            if (arg != null) {
                Set<ConstraintViolation<Object>> violations = validator.validate(arg);
                if (!violations.isEmpty()) {
                    StringBuilder errorMessage = new StringBuilder();
                    for (ConstraintViolation<Object> violation : violations) {
                        errorMessage.append(violation.getMessage()).append(" ");
                    }
                    throw new IllegalArgumentException("Invalid parameters: " + errorMessage.toString().trim());
                }
            }
        }
    }
}
3. 实现参数校验

在实际需要校验的类和方法中,使用Java Bean Validation提供的注解。

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class DemoService {

    @ValidatedParams
    public void process(@NotNull(message = "Parameter cannot be null") String data,
                        @Size(min = 5, message = "Length must be at least 5") String description) {
        // 业务逻辑处理
        System.out.println("Processing: " + data + " with description: " + description);
    }
}
4. 配置Spring环境

确保相关的AOP和Validation依赖在你的Spring项目中已经引入,通常在pom.xml中添加:

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

 这种设计提供了高水平的灵活性,并且避免了方法内部的冗长校验逻辑。通过AOP,我们能够在不干扰业务逻辑的前提下,集中处理参数校验,从而提升代码的整体可读性和可维护性。同时,利用注解的自描述性使得方法的要求一目了然。这种结构符合现代软件开发中倡导的单一职责原则(SRP)。

 

 

 

 

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。 这样,我们就可以通过自定义注解来进行数据验证了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值