自定義參數校驗註解

註解定義

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 = MyInterfaceRealize.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 class MyInterfaceRealize 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)
...........................................

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章