自定义参数校验注解

9 篇文章 0 订阅

注解定义

Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据。为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。
Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取注解内容。在编译器生成类文件时,注解可以被嵌入到字节码中。Java虚拟机可以保留注解内容,在运行时可以获取到注解内容。

元注解

  • @Target - 标记注解注释哪种 Java 成员。
  • @Retention - 标记注解存储方式
  • @Documented - 标记注解是否包含在Javadoc用户文档中。
  • @Inherited - 标记注解可以被继承

1.@Target

限制注解的注释类型,类型在 ElementType 中

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,
    /** Field declaration (includes enum constants) */
    FIELD,
    /** Method declaration */
    METHOD,
    /** Formal parameter declaration */
    PARAMETER,
    /** Constructor declaration */
    CONSTRUCTOR,
    /** Local variable declaration */
    LOCAL_VARIABLE,
    /** Annotation type declaration */
    ANNOTATION_TYPE,
    /** Package declaration */
    PACKAGE,
    /** Type parameter declaration*/
    TYPE_PARAMETER,
    /** Use of a type*/
    TYPE_USE
}

2.@Retention

规定注解的存储方式,要保留多久,参数在 RetentionPolicy 中

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     * 保留在源代码中,编译时忽略
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     * 保留在字节码中,VM 运行时忽略
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     * 运行 VM 时保留,因此可以通过反射进行读取
     */
    RUNTIME
}

模拟场景

校验请求参数,参数为手机号,校验其格式的正确与否

1.自定义注解体

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义手机号码校验注解
 *
 * @author YoonaLt
 * @date 2019-10-14
 */
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AbstractInterfaceRealize.class)  // 约束类
public @interface MyAnnotation {
    String message() default "数据格式有误";

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

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

注解内的     Class<?>[] groups() default {};     Class<? extends Payload>[] payload() default  {}; 不要忘记,且名称固定,否则使用时报错

javax.validation.ConstraintDefinitionException: HV000074: com.yoona.MyAnnotation contains Constraint annotation, but does not contain a payload(或者为groups) parameter.

2.编写注解验证器

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * 注解验证器
 *
 * @author YoonaLt
 * @date 2019-10-14
 */
public abstract class AbstractInterfaceRealizee implements ConstraintValidator<MyAnnotation, String> {
    // ConstraintValidator<MyAnnotation, String> String为要注释的数据的类型
    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        // 号码长度
        int len = 11;
        if (value == null || "".equals(value) || value.length() != len) {
            return false;
        }
        // 测试的校验规则
        String regex = "^1[3|4|5|7|8][0-9]\\d{4,8}$";
        return value.matches(regex);
    }
}

3.测试

import com.yoona.custom.MyAnnotation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author YoonaLt
 * @date 2019-10-14
 */
@Validated  // 这里使用这个注解使我们自定义的注解生效
@RestController
@RequestMapping(value = "test")
public class TestAnnotation {

    @GetMapping(value = "test")
    public void myTest(@MyAnnotation String number) {
    }
}

当参数 number 不符合验证器内的规定时,我们可以看到报错信息

javax.validation.ConstraintViolationException: myTest.number: 数据格式有误
	at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:116)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
...........................................

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用自定义注解校验请求参数。下面是一个示例: 首先,创建一个自定义注解类,例如 `@RequestParamValid`: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface RequestParamValid { String value() default ""; } ``` 然后,在你的控制器方法中使用 `@RequestParamValid` 注解来标记需要校验参数: ```java @PostMapping("/example") public String exampleMethod(@RequestParam @RequestParamValid String parameter) { // ... } ``` 接下来,你可以创建一个切面来处理参数校验逻辑。切面可以使用 Spring 提供的 `HandlerMethodArgumentResolver` 接口来实现: ```java import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; @Component public class RequestParamValidResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(RequestParamValid.class); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { // 在这里进行参数校验逻辑,可以使用各种方式来校验参数 // 例如,你可以使用 Hibernate Validator 进行校验 // 如果参数校验失败,可以抛出异常或返回错误信息 // 如果参数校验通过,可以返回参数的值 // 这里只是一个示例,假设参数不能为空 Object argumentValue = webRequest.getParameter(parameter.getParameterName()); if (argumentValue == null || argumentValue.toString().isEmpty()) { throw new IllegalArgumentException("参数校验失败"); } return argumentValue; } } ``` 最后,将切面注册到 Spring 容器中,以便生效。你可以在配置类中使用 `@EnableWebMvc` 注解来开启 Spring MVC 的相关功能: ```java import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.List; @Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { private final RequestParamValidResolver requestParamValidResolver; public WebConfig(RequestParamValidResolver requestParamValidResolver) { this.requestParamValidResolver = requestParamValidResolver; } @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(requestParamValidResolver); } } ``` 现在,当请求进入控制器方法时,会自动触发参数校验逻辑。如果参数校验失败,将会抛出异常或返回错误信息。如果校验通过,控制器方法将会正常执行。 这只是一个简单的示例,你可以根据实际需求进行更复杂的参数校验逻辑。希望对你有帮助!如有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值