Hibernate Validator 自定義校驗注解 SpringBoot


先說一下實現思路:

1.我們需要創建一個自定義注解和對應的校驗類;注解用於定義使用校驗的形式,校驗類用於定義校驗的方式(如何去進行校驗)。

2.然后將注解和校驗類進行關聯。

3.最后在我們需要校驗的實體類里面使用注解。

 

下面是我創建的三個自定義注解,分別 實現了,對於yyyyMMdd(默認,也可以更改)日期格式,HHmmss(默認,也可以更改 )時間格式,枚舉值格式校驗。

添加三個自定義注解,@Date,@Time和@Enums

@Date用於校驗日期,@Time用於校驗時間,@Enums用於校驗枚舉值

項目結構:

 

 

 

一些項目框架代碼:

項目依賴:

 1 <dependencies>
 2         <dependency>
 3             <groupId>org.springframework.boot</groupId>
 4             <artifactId>spring-boot-starter-validation</artifactId>
 5         </dependency>
 6         <dependency>
 7             <groupId>org.springframework.boot</groupId>
 8             <artifactId>spring-boot-starter-web</artifactId>
 9         </dependency>
10 
11         <dependency>
12             <groupId>org.springframework.boot</groupId>
13             <artifactId>spring-boot-starter-test</artifactId>
14             <scope>test</scope>
15             <exclusions>
16                 <exclusion>
17                     <groupId>org.junit.vintage</groupId>
18                     <artifactId>junit-vintage-engine</artifactId>
19                 </exclusion>
20             </exclusions>
21         </dependency>
22    </dependencies>

Date.java Date枚舉定義:

 1 package com.hgd.validatortest.annotation;
 2 
 3 import com.hgd.validatortest.Validators.DateValidator;
 4 import javax.validation.Constraint;
 5 import javax.validation.Payload;
 6 import java.lang.annotation.ElementType;
 7 import java.lang.annotation.Retention;
 8 import java.lang.annotation.RetentionPolicy;
 9 import java.lang.annotation.Target;
10 
11 @Target({ ElementType.FIELD})
12 @Retention(RetentionPolicy.RUNTIME)
13 @Constraint(validatedBy = DateValidator.class)
14 public @interface Date {
15     String message() default "日期格式錯誤";
16 
17     Class<?>[] groups() default { };
18 
19     Class<? extends Payload>[] payload() default { };
20 
21     String formatter() default "yyyyMMdd";
22 }

注:枚舉類這里的message,如果你在使用的時候,注解沒有指定message的值,則最終校驗結果返回的錯誤信息,就是這個默認的錯誤信息。formatter指定的是你需要校驗的日期格式,可以在使用注解時指定,覆蓋默認的日期格式。

Date 校驗邏輯實現類: DateValidator.java

 1 package com.hgd.validatortest.Validators;
 2 
 3 import com.hgd.validatortest.annotation.Date;
 4 
 5 import javax.validation.ConstraintValidator;
 6 import javax.validation.ConstraintValidatorContext;
 7 import java.time.LocalDate;
 8 import java.time.format.DateTimeFormatter;
 9 
10 public class DateValidator implements ConstraintValidator<Date, String> {
11 
12     private String formatter;
13 
14     @Override
15     public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
16         if(s == null)
17             return true;
18         try {
19             LocalDate localDate = LocalDate.parse(s, DateTimeFormatter.ofPattern(formatter));
20         }catch (Exception e){
21             System.out.println("異常信息:"+e.getMessage());
22             return false;
23         }
24         return true;
25     }
26 
27     /**
28      * 獲取注解中的值
29      */
30     @Override
31     public void initialize(Date date) {
32         formatter = date.formatter();
33     }
34 
35 }

 

Time校驗枚舉定義:Time.java

 1 package com.hgd.validatortest.annotation;
 2 
 3 import com.hgd.validatortest.Validators.TimeValidator;
 4 
 5 import javax.validation.Constraint;
 6 import javax.validation.Payload;
 7 import java.lang.annotation.ElementType;
 8 import java.lang.annotation.Retention;
 9 import java.lang.annotation.RetentionPolicy;
10 import java.lang.annotation.Target;
11 
12 @Target({ ElementType.FIELD})
13 @Retention(RetentionPolicy.RUNTIME)
14 @Constraint(validatedBy = TimeValidator.class)
15 public @interface Time {
16     String message() default "時間格式錯誤";
17 
18     Class<?>[] groups() default { };
19 
20     Class<? extends Payload>[] payload() default { };
21 
22     String formatter() default "HHmmss";
23 }

Time校驗邏輯實現類:TimeValidator.java

 1 package com.hgd.validatortest.Validators;
 2 
 3 import com.hgd.validatortest.annotation.Time;
 4 
 5 import javax.validation.ConstraintValidator;
 6 import javax.validation.ConstraintValidatorContext;
 7 import java.time.LocalTime;
 8 import java.time.format.DateTimeFormatter;
 9 
10 public class TimeValidator implements ConstraintValidator<Time, String> {
11     private String formatter;
12 
13     @Override
14     public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
15         if(s == null)
16             return true;
17         try {
18             LocalTime localTime = LocalTime.parse(s, DateTimeFormatter.ofPattern(formatter));
19             System.out.println("哈哈");
20         }catch (Exception e){
21             System.out.println("異常信息:"+e.getMessage());
22             return false;
23         }
24         return true;
25     }
26 
27     /**
28      * 獲取注解中的值
29      */
30     @Override
31     public void initialize(Time time) {
32         formatter = time.formatter();
33     }
34 }

 

Enums校驗的枚舉定義:Enums.java

 1 package com.hgd.validatortest.annotation;
 2 
 3 import com.hgd.validatortest.Validators.EnumsValidator;
 4 import com.hgd.validatortest.Validators.TimeValidator;
 5 
 6 import javax.validation.Constraint;
 7 import javax.validation.Payload;
 8 import java.lang.annotation.ElementType;
 9 import java.lang.annotation.Retention;
10 import java.lang.annotation.RetentionPolicy;
11 import java.lang.annotation.Target;
12 
13 @Target({ ElementType.FIELD})
14 @Retention(RetentionPolicy.RUNTIME)
15 @Constraint(validatedBy = EnumsValidator.class)
16 public @interface Enums {
17     String message() default "暫不支持的枚舉值";
18 
19     Class<?>[] groups() default { };
20 
21     Class<? extends Payload>[] payload() default { };
22 
23     String[] enumCode ();
24 }

Enums 注解的校驗邏輯實現類:EnumsValidator.java

 1 package com.hgd.validatortest.Validators;
 2 
 3 import com.hgd.validatortest.annotation.Enums;
 4 
 5 import javax.validation.ConstraintValidator;
 6 import javax.validation.ConstraintValidatorContext;
 7 import java.util.Arrays;
 8 import java.util.HashSet;
 9 import java.util.Set;
10 
11 public class EnumsValidator implements ConstraintValidator<Enums, String> {
12 
13     private Set<String> enumSet;
14     @Override
15     public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
16         if(s==null)
17             return true;
18         return enumSet.contains(s);
19     }
20     /**
21      * 獲取注解中的值
22      */
23     @Override
24     public void initialize(Enums enums) {
25         enumSet = new HashSet<>(Arrays.asList(enums.enumCode()));
26     }
27 }

 

 

待校驗的實體類:User.java

 1 package com.hgd.validatortest.bean;
 2 
 3 import com.hgd.validatortest.annotation.Date;
 4 import com.hgd.validatortest.annotation.Enums;
 5 import com.hgd.validatortest.annotation.Time;
 6 import org.hibernate.validator.constraints.Length;
 7 
 8 import javax.validation.constraints.Digits;
 9 import javax.validation.constraints.NotBlank;
10 import javax.validation.constraints.PositiveOrZero;
11 
12 public class User {
13 
14     @NotBlank(message = "用戶名不能為空")
15     @Length(max = 8,message = "用戶名長度最大為8")
16     private String userName;
17 
18     private String password;
19 
20     @NotBlank(message = "金額")
21     @Digits(integer = 20,fraction = 2,message = "金額格式錯誤")
22     @PositiveOrZero(message = "金額需要為正數")
23     private String amount;
24 
25     @Enums(enumCode = {"1","2"})
26     private String operatorType;
27 
28     @Date(message = "出生日期格式不正確")
29     private String birthDate;
30 
31     @Time(message = "出生時間格式不正確")
32     private String birthTime;
33 
34     public String getBirthTime() {
35         return birthTime;
36     }
37 
38     public void setBirthTime(String birthTime) {
39         this.birthTime = birthTime;
40     }
41 
42     public String getBirthDate() {
43         return birthDate;
44     }
45 
46     public void setBirthDate(String birthDate) {
47         this.birthDate = birthDate;
48     }
49 
50     public String getUserName() {
51         return userName;
52     }
53 
54     public void setUserName(String userName) {
55         this.userName = userName;
56     }
57 
58     public String getPassword() {
59         return password;
60     }
61 
62     public void setPassword(String password) {
63         this.password = password;
64     }
65 
66     public String getAmount() {
67         return amount;
68     }
69 
70     public void setAmount(String amount) {
71         this.amount = amount;
72     }
73 
74     public String getOperatorType() {
75         return operatorType;
76     }
77 
78     @Override
79     public String toString() {
80         return "User{" +
81                 "userName='" + userName + '\'' +
82                 ", password='" + password + '\'' +
83                 ", amount='" + amount + '\'' +
84                 ", operatorType='" + operatorType + '\'' +
85                 '}';
86     }
87 
88     public void setOperatorType(String operatorType) {
89         this.operatorType = operatorType;
90     }
91 }

 

Spring Boot的Controller:TestController.java

 1 package com.hgd.validatortest.controller;
 2 
 3 import com.hgd.validatortest.bean.User;
 4 import org.springframework.web.bind.annotation.PostMapping;
 5 import org.springframework.web.bind.annotation.RequestBody;
 6 import org.springframework.web.bind.annotation.RequestMapping;
 7 import org.springframework.web.bind.annotation.RestController;
 8 
 9 import javax.validation.Valid;
10 
11 @RestController
12 @RequestMapping("/test")
13 public class TestController {
14     @PostMapping("/user")
15     public String testUser(@RequestBody  @Valid User user){
16         String resultStr= "";
17         System.out.println(user);
18         return resultStr;
19     }
20 
21 }

 

Spring Boot 自定義全局異常捕獲: MyExceptionHandler.java 這里是參考的網絡上的代碼:

 1 package com.hgd.validatortest.handler;
 2 
 3 import org.springframework.validation.BindException;
 4 import org.springframework.validation.BindingResult;
 5 import org.springframework.validation.ObjectError;
 6 import org.springframework.web.bind.MethodArgumentNotValidException;
 7 import org.springframework.web.bind.annotation.ExceptionHandler;
 8 import org.springframework.web.bind.annotation.RestControllerAdvice;
 9 
10 import java.util.HashMap;
11 import java.util.Map;
12 
13 @RestControllerAdvice
14 public class MyExceptionHandler {
15     //json格式
16     @ExceptionHandler(value = MethodArgumentNotValidException.class)
17     public Map<String,Object> errorHandler(MethodArgumentNotValidException ex) {
18         StringBuilder errorMsg = new StringBuilder();
19         BindingResult re = ex.getBindingResult();
20         for (ObjectError error : re.getAllErrors()) {
21             errorMsg.append(error.getDefaultMessage()).append(",");
22         }
23         errorMsg.delete(errorMsg.length() - 1, errorMsg.length());
24         Map<String,Object> map = new HashMap();
25         map.put("code", 400);
26         map.put("msg", errorMsg.toString());
27         return map;
28     }
29 
30 
31     //表單格式
32     @ExceptionHandler(value = BindException.class)
33     public Map<String,Object> errorHandler(BindException ex) {
34         BindingResult result = ex.getBindingResult();
35         StringBuilder errorMsg = new StringBuilder();
36         for (ObjectError error : result.getAllErrors()) {
37             errorMsg.append(error.getDefaultMessage()).append(",");
38         }
39         errorMsg.delete(errorMsg.length() - 1, errorMsg.length());
40         Map<String,Object> map = new HashMap();
41         map.put("code", 400);
42         map.put("msg", errorMsg.toString());
43         return map;
44     }
45 }

 

准備完成后,開始測試,工具用的是Postman:

 


免責聲明!

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



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