JAVA裡自訂註解來進行資料驗證

來源:互聯網
上載者:User

標籤:bind   使用   .class   val   ali   nts   erro   integer   情況   

API開發中經常會遇到一些對請求資料進行驗證的情況,這時候如果使用註解就有兩個好處,一是驗證邏輯和商務邏輯分離,代碼清晰,二是驗證邏輯可以輕鬆複用,只需要在要驗證的地方加上註解就可以。

Java提供了一些基本的驗證註解,比如@NotNull@Size,但是更多情況下需要自訂驗證邏輯,這時候就可以自己實現一個驗證註解,方法很簡單,僅需要兩個東西:

  • 一個自訂的註解,並且指定驗證器
  • 一個驗證器的實現
自訂驗證註解

考慮有一個API,接收一個Student對象,並希望對象裡的age域的值是奇數,這時候就可以建立以下註解:

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = AgeValidator.class)public @interface Odd {    String message() default "Age Must Be Odd";    Class<?>[] groups() default {};    Class<? extends Payload>[] payload() default {};}

其中:

  • @Target指明這個註解要作用在什麼地方,可以是對象、域、構造器等,因為要作用在age域上,因此這裡選擇FIELD
  • @Retention指明了註解的生命週期,可以有SOURCE(僅儲存在源碼中,會被編譯器丟棄),CLASS(在class檔案中可用,會被VM丟棄)以及RUNTIME(在運行期也被保留),這裡選擇了生命週期最長的RUNTIME
  • @Constraint是最關鍵的,它表示這個註解是一個驗證註解,並且指定了一個實現驗證邏輯的驗證器
  • message()指明了驗證失敗後返回的訊息,此方法為@Constraint要求
  • groups()payload()也為@Constraint要求,可預設為空白,詳細用途可以查看@Constraint文檔
建立驗證器

有了註解之後,就需要一個驗證器來實現驗證邏輯:

public class AgeValidator implements ConstraintValidator<Odd,Integer> {    @Override    public void initialize(Odd constraintAnnotation) {    }    @Override    public boolean isValid(Integer age, ConstraintValidatorContext constraintValidatorContext) {        return age % 2 != 0;    }}

其中:

  • 驗證器有兩個型別參數,第一個是所屬的註解,第二個是註解作用地方的類型,這裡因為作用在age上,因此這裡用了Integer
  • initialize()可以在驗證開始前調用註解裡的方法,從而擷取到一些註解裡的參數,這裡用不到
  • isValid()就是判斷是否合法的地方
應用註解

註解和驗證器建立好之後,就可以使用註解了:

public class Student {    @Odd    private int age;    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}
@RestControllerpublic class StudentResource {    @PostMapping("/student")    public String addStudent(@Valid @RequestBody Student student) {        return "Student Created";    }}

在需要啟用驗證的地方加上@Valid註解,這時候如果請求裡的Student年齡不是奇數,就會得到一個400響應:

{    "timestamp": "2018-08-15T17:01:44.598+0000",    "status": 400,    "error": "Bad Request",    "errors": [        {            "codes": [                "Odd.student.age",                "Odd.age",                "Odd.int",                "Odd"            ],            "arguments": [                {                    "codes": [                        "student.age",                        "age"                    ],                    "arguments": null,                    "defaultMessage": "age",                    "code": "age"                }            ],            "defaultMessage": "Age Must Be Odd",            "objectName": "student",            "field": "age",            "rejectedValue": 12,            "bindingFailure": false,            "code": "Odd"        }    ],    "message": "Validation failed for object=‘student‘. Error count: 1",    "path": "/student"}

也可以手動來處理錯誤,加上一個BindingResult來接收驗證結果即可:

@RestControllerpublic class StudentResource {    @PostMapping("/student")    public String addStudent(@Valid @RequestBody Student student, BindingResult validateResult) {        if (validateResult.hasErrors()) {            return validateResult.getAllErrors().get(0).getDefaultMessage();        }        return "Student Created";    }}

這時候如果驗證出錯,便只會返回一個狀態為200,內容為Age Must Be Odd的響應。

JAVA裡自訂註解來進行資料驗證

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.