Springboot--元注解及自定義注解(表單驗證)


  本文簡單說明一下元注解,然后對元注解中的@Retention做深入的討論,在文章最后使用元注解寫一個自定義注解來結尾。

一、結論:

@Target:注解的作用目標

  @Target(ElementType.TYPE)——接口、類、枚舉、注解
  @Target(ElementType.FIELD)——字段、枚舉的常量
  @Target(ElementType.METHOD)——方法
  @Target(ElementType.PARAMETER)——方法參數
  @Target(ElementType.CONSTRUCTOR) ——構造函數
  @Target(ElementType.LOCAL_VARIABLE)——局部變量
  @Target(ElementType.ANNOTATION_TYPE)——注解
  @Target(ElementType.PACKAGE)——包

@Retention:注解的保留位置

  RetentionPolicy.SOURCE:這種類型的Annotations只在源代碼級別保留,編譯時就會被忽略,在class字節碼文件中不包含。
  RetentionPolicy.CLASS:這種類型的Annotations編譯時被保留,默認的保留策略,在class文件中存在,但JVM將會忽略,運行時無法獲得。
  RetentionPolicy.RUNTIME:這種類型的Annotations將被JVM保留,所以他們能在運行時被JVM或其他使用反射機制的代碼所讀取和使用。
@Document:說明該注解將被包含在javadoc中
@Inherited:說明子類可以繼承父類中的該注解

 

二、場景與樣例

  此處對@Retention做特殊說明。

  RetentionPolicy.SOURCE,編譯后的class文件不包含@Retention注釋,使用在編譯階段,主要是在編譯時做一些操作,例如:@Override和@SuppressWarnings(@Override:改注解向編譯器說明被注解元素是重寫的父類的一個元素。在重寫父類元素的時候此注解並非強制性的,不過可以在重寫錯誤時幫助編譯器產生錯誤以提醒我們。比如子類方法的參數和父類不匹配,或返回值類型不同;編譯通過后,方法上不再有@Override注解;@SuppressWarnings:在編譯時抑制編譯報錯)。

  RetentionPolicy.CLASS,編譯后在class文件中仍然存在,但是運行時不會被JVM調用,即使是使用反射也不無法調用該注解,但是要是具體說他與RetentionPolicy.SOURCE的區別,除了是否會存在於class文件上之外,還沒有找到實質性的區別(很有可能的區別是:RetentionPolicy.SOURCE僅僅是給應用層開發人員用的,RetentionPolicy.CLASS 需要應用層和底層系統開發人員配合使用的,所以僅僅是應用層開發的我們是一臉懵逼)

 

三、自定義注解(以自定義日期校驗注解為例)

  1、自定義注解

package com.example.demo.utils;

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;

@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DateTimeValidator.class)
public @interface DateTime {
    String message() default "格式錯誤";
    String format() default "YYYY-MM-DD";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

}

  其中@Constraint必須添加,改注解指定自定義注解的具體實現類。

  2、自定義注解實現類(校驗邏輯實現類)

package com.example.demo.utils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateTimeValidator implements ConstraintValidator<DateTime, String> {

    private DateTime dateTime;

    @Override
    public void initialize(DateTime constraintAnnotation) {
        this.dateTime = constraintAnnotation;
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if(context == null){
            return true;

        }
        String format = dateTime.format();
        if (value.length() != format.length()) {
            return false;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        try {
            simpleDateFormat.parse(value);
        } catch (ParseException e) {
            return false;
        }
        return true;
    }
}

  3、自定義注解使用

@Validated
@Controller
@RequestMapping("/test")
@Api(value = "SpringBoot測試接口2")
public class UserTestController2 {

    @ResponseBody
    @PostMapping(value ="/validated2")
    @ApiOperation(value="validated表單驗證測試")
    @ApiImplicitParams( {@ApiImplicitParam(paramType="query", name = "date", value = "日期", dataType = "String")})
    public String validated2(@DateTime(message = "格式錯誤啦啦啦啦",format = "yyyy-mm-dd") String date){
        return "OK";
    }


    @ResponseBody
    @PostMapping(value ="/validated3")
    @ApiOperation(value="validated表單驗證測試")
    @ApiImplicitParams( {@ApiImplicitParam(paramType="query", name = "date", value = "日期", dataType = "String")})
    public String validated3(@DateTime String date){
        return "OK";
    }
}

  4、驗證

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM