Spring Boot自定義註解與驗證

註解原理與自定義註解

1、引入依賴:

<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

2、定義註解@JachinLength

利用該註解驗證某字符串屬性長度必須爲指定長度

package com.jachin.zhujie;

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})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = LengthValidatorClass.class) // 指定驗證類
public @interface JachinLength {
    int length() default 11;          // 允許字符串長度
    String message() default "kkkkk";  // 自定義的錯誤提示信息
  	// 下面這兩個必須有
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

下面做幾點說明:

1、註解的定義有點像定義接口 interface,但唯一不同的是前面需要加一個 @符號

2、註解的成員變量只能使用基本類型、 String或者 enum枚舉,比如 int可以,但 Integer這種包裝類型就不行。

3、像上面 @Target@Retention這種加在註解定義上面的註解,稱爲 “元註解”,元註解就是專門用於給註解添加註解的註解

4、 @Target(xxx) 用來說明該自定義註解可以用在什麼位置,比如:

  • ElementType.FIELD說明自定義的註解可以用於類的變量
  • ElementType.METHOD說明自定義的註解可以用於類的方法
  • ElementType.TYPE說明自定義的註解可以用於類本身、接口或 enum類型

5、 @Retention(xxx) 用來說明你自定義註解的生命週期,比如:

  • @Retention(RetentionPolicy.RUNTIME):表示註解可以一直保留到運行時,因此可以通過反射獲取註解信息
  • @Retention(RetentionPolicy.CLASS)表示註解被編譯器編譯進 class文件,但運行時會忽略
  • @Retention(RetentionPolicy.SOURCE)表示註解僅在源文件中有效,編譯時就會被忽略

所以聲明週期從長到短分別爲:RUNTIME > CLASS > SOURCE

6、@Constraint:指定驗證屬性的類。

  • message()指明瞭驗證失敗後返回的消息,此方法爲@Constraint要求

  • groups()和payload()也爲@Constraint要求,可默認爲空,詳細用途可以查看@Constraint文檔


3、實現驗證類LengthValidatorClass

package com.jachin.zhujie;

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

/**
 * @description:
 * @Author: JachinDo
 * @Date: 2020/03/09 11:55
 */

public class LengthValidatorClass implements ConstraintValidator<JachinLength, String> { // 第一個參數是註解類,第二個註解是作用的對象類型
   private JachinLength length;

	// 將註解提取出來,底層利用反射生成註解的代理類
   @Override
   public void initialize(JachinLength constraint) {
      this.length = constraint;
   }
	// 驗證邏輯
   @Override
   public boolean isValid(String obj, ConstraintValidatorContext context) {
      return obj.length() != length.length() ? false : true;
   }
}


4、實體類與使用controller處驗證字段

實體類:

package com.jachin.zhujie;

import lombok.Data;

/**
 * @description:
 * @Author: JachinDo
 * @Date: 2020/03/09 12:06
 */
@Data
public class Person {
	// 之前定義時默認長度爲11
    @JachinLength(message = "長度錯誤!")
    private String phone;
}

controller:

package com.jachin.zhujie;

import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * @description:
 * @Author: JachinDo
 * @Date: 2020/03/09 13:02
 */
@RestController
@RequestMapping("/anno")

public class TestZhujie {
    @PostMapping("/phone")
    public String print(@Valid Person person,
                      BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            System.out.println("錯誤 " + person);
            throw new Exception(bindingResult.getFieldError().getDefaultMessage());
        }
        return person.toString();
    }
}


結果:

當輸入phone長度不爲11時:

在這裏插入圖片描述

爲11時:
在這裏插入圖片描述

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