JAVA中通過自定義注解進行數(shù)據(jù)驗證的方法
前言
最近為了工作也為了更加深入了解掌握java注解的使用,決定自定義注解來實現(xiàn)數(shù)據(jù)驗證。
API開發(fā)中經(jīng)常會遇到一些對請求數(shù)據(jù)進行驗證的情況,這時候如果使用注解就有兩個好處,一是驗證邏輯和業(yè)務(wù)邏輯分離,代碼清晰,二是驗證邏輯可以輕松復(fù)用,只需要在要驗證的地方加上注解就可以。
Java提供了一些基本的驗證注解,比如@NotNull、@Size,但是更多情況下需要自定義驗證邏輯,這時候就可以自己實現(xiàn)一個驗證注解,方法很簡單,僅需要兩個東西:
- 一個自定義的注解,并且指定驗證器
- 一個驗證器的實現(xiàn)
自定義驗證注解
考慮有一個API,接收一個Student對象,并希望對象里的age域的值是奇數(shù),這時候就可以創(chuàng)建以下注解:
@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指明這個注解要作用在什么地方,可以是對象、域、構(gòu)造器等,因為要作用在age域上,因此這里選擇FIELD
- @Retention指明了注解的生命周期,可以有SOURCE(僅保存在源碼中,會被編譯器丟棄),CLASS(在class文件中可用,會被VM丟棄)以及RUNTIME(在運行期也被保留),這里選擇了生命周期最長的RUNTIME
- @Constraint是最關(guān)鍵的,它表示這個注解是一個驗證注解,并且指定了一個實現(xiàn)驗證邏輯的驗證器
- message()指明了驗證失敗后返回的消息,此方法為@Constraint要求
- groups()和payload()也為@Constraint要求,可默認為空,詳細用途可以查看@Constraint文檔
創(chuàng)建驗證器
有了注解之后,就需要一個驗證器來實現(xiàn)驗證邏輯:
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;
}
}
其中:
- 驗證器有兩個類型參數(shù),第一個是所屬的注解,第二個是注解作用地方的類型,這里因為作用在age上,因此這里用了Integer
- initialize()可以在驗證開始前調(diào)用注解里的方法,從而獲取到一些注解里的參數(shù),這里用不到
- isValid()就是判斷是否合法的地方
應(yīng)用注解
注解和驗證器創(chuàng)建好之后,就可以使用注解了:
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;
}
}
@RestController
public class StudentResource {
@PostMapping("/student")
public String addStudent(@Valid @RequestBody Student student) {
return "Student Created";
}
}
在需要啟用驗證的地方加上@Valid注解,這時候如果請求里的Student年齡不是奇數(shù),就會得到一個400響應(yīng):
{
"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來接收驗證結(jié)果即可:
@RestController
public 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";
}
}
這時候如果驗證出錯,便只會返回一個狀態(tài)為200,內(nèi)容為Age Must Be Odd的響應(yīng)。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
spring boot下mybatis配置雙數(shù)據(jù)源的實例
這篇文章主要介紹了spring boot下mybatis配置雙數(shù)據(jù)源的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
如何基于Springboot完成新增員工功能并設(shè)置全局異常處理器
最近工作中遇到了做一個管理員工信息的功能,下面這篇文章主要給大家介紹了關(guān)于如何基于Springboot完成新增員工功能并設(shè)置全局異常處理器的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2022-11-11
使用springboot對外部靜態(tài)資源文件的處理操作
這篇文章主要介紹了使用springboot對外部靜態(tài)資源文件的處理操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
java使用Logback配置輸出日志內(nèi)容到文件示例代碼
這篇文章主要介紹了java?Logback輸出日志內(nèi)容到文件,要將logger.info的信息輸出到文件,您可以使用Logback配置,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2023-09-09
SpringBoot2 task scheduler 定時任務(wù)調(diào)度器四種方式
這篇文章主要介紹了SpringBoot2 task scheduler 定時任務(wù)調(diào)度器四種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-03-03

