溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springboot validator枚舉值校驗功能的實現(xiàn)

發(fā)布時間:2021-08-30 15:21:23 來源:億速云 閱讀:133 作者:chen 欄目:編程語言

本篇內(nèi)容介紹了“springboot validator枚舉值校驗功能的實現(xiàn)”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一、前言

在spring項目中,校驗參數(shù)功能使用hibernate validator是一個不錯的選擇,我們的項目中也是使用它來進行校驗的,省去了很多難看的校驗邏輯,使代碼的可讀性也大大增加,本章將帶你使用hibernate validator自定義注解功能實現(xiàn)一個 枚舉值校驗的邏輯。

二、需求

我們先明確下我們的需求,在程序開發(fā)過程中,我們經(jīng)常會有一個對象的屬性值只能出現(xiàn)在一組常量中的校驗需求,例如:用戶性別字段gender只能等于MALE/FEMALE這兩個其中一個值,用戶賬號的狀態(tài)status只能等于:

NORMAL/DISABLED/DELETED其中一個等等,那么我們怎么能更好的校驗這個參數(shù)呢?我們想擁有一個java注解,把它標記在所要校驗的字段上,當開啟hibernate validator校驗時,就可以校驗其字段值是否正確。

三、實現(xiàn)方案

上面提到的一組常量值,我們第一反應應該是定義一個枚舉類,盡量不要放在一個統(tǒng)一的constants類下,這樣當系統(tǒng)一旦龐大起來,常量是很難維護和查找的,所以前期代碼也應該有一些規(guī)范性約束,這里我們約定一組常量值時使用枚舉,并把該枚舉類放在對應的類對象里(以上述所說的用戶功能為例,我們應該把GenerEnum、UserStatusEnum枚舉放在User.java下,方便查找)

這里我們定義一個叫EnumValue.java的注解類,其下有兩個主要參數(shù)一個是enumClass用于指定枚舉類,enumMethod指定要校驗的方法,下面我們看代碼實現(xiàn)。

四、代碼實現(xiàn)

package com.zhuma.demo.annotation; import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method; import javax.validation.Constraint;import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;import javax.validation.Payload; import org.assertj.core.util.Strings; /** * @desc 校驗枚舉值有效性 * * @author zhumaer * @since 10/17/2017 3:13 PM */@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = EnumValue.Validator.class)public @interface EnumValue {   String message() default "{custom.value.invalid}";   Class<?>[] groups() default {};   Class<? extends Payload>[] payload() default {};   Class<? extends Enum<?>> enumClass();   String enumMethod();   class Validator implements ConstraintValidator<EnumValue, Object> {     private Class<? extends Enum<?>> enumClass;    private String enumMethod;     @Override    public void initialize(EnumValue enumValue) {      enumMethod = enumValue.enumMethod();      enumClass = enumValue.enumClass();    }     @Override    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {      if (value == null) {        return Boolean.TRUE;      }       if (enumClass == null || enumMethod == null) {        return Boolean.TRUE;      }       Class<?> valueClass = value.getClass();       try {        Method method = enumClass.getMethod(enumMethod, valueClass);        if (!Boolean.TYPE.equals(method.getReturnType()) && !Boolean.class.equals(method.getReturnType())) {          throw new RuntimeException(Strings.formatIfArgs("%s method return is not boolean type in the %s class", enumMethod, enumClass));        }         if(!Modifier.isStatic(method.getModifiers())) {          throw new RuntimeException(Strings.formatIfArgs("%s method is not static method in the %s class", enumMethod, enumClass));        }           Boolean result = (Boolean)method.invoke(null, value);        return result == null ? false : result;      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {        throw new RuntimeException(e);      } catch (NoSuchMethodException | SecurityException e) {        throw new RuntimeException(Strings.formatIfArgs("This %s(%s) method does not exist in the %s", enumMethod, valueClass, enumClass), e);      }    }   }}

備注

1) 自定義注解需要實現(xiàn)ConstraintValidator校驗類,這里我們定義一個叫Validator的類來實現(xiàn)它,同時實現(xiàn)它下面的兩個方法initialize、isValid,一個是初始化參數(shù)的方法,另一個就是校驗邏輯的方法,本例子中我們將校驗類定義在該注解內(nèi),用@Constraint(validatedBy = EnumValue.Validator.class)注解指定校驗類,內(nèi)部邏輯實現(xiàn)比較簡單就是使用了靜態(tài)類反射調(diào)用驗證方法的方式。

2) 對于被校驗的方法我們要求,它必須是返回值類型為Boolean或boolean,并且必須是一個靜態(tài)的方法,返回返回值為null時我們認為是校驗不通過的,按false邏輯走。

五、使用演示

校驗的目標對象類

package com.zhuma.demo.model.po; import java.io.Serializable;import java.util.Date; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.Length;import org.hibernate.validator.constraints.NotBlank;import org.hibernate.validator.constraints.Range; import com.zhuma.demo.annotation.EnumValue;import com.zhuma.demo.validator.CreateGroup; /** * @desc 用戶PO  * @author zhumaer * @since 6/15/2017 2:48 PM */public class User implements Serializable {   private static final long serialVersionUID = 2594274431751408585L;   /**   * 用戶ID   */  private Long id;   /**   * 登錄密碼   */  @NotBlank  private String pwd;   /**   * 昵稱   */  @NotBlank  @Length(min=1, max=64)  private String nickname;   /**   * 頭像   */  private String img;   /**   * 電話   */  @Pattern(regexp = "^1[3-9]\\d{9}$")  private String phone;   /**   * 賬號狀態(tài)   */  @EnumValue(enumClass=UserStatusEnum.class, enumMethod="isValidName")  private String status;   /**   * 最新的登錄時間   */  private Date latestLoginTime;   /**   * 最新的登錄IP   */  private String latestLoginIp;   private Date createTime;  private Date updateTime;     /**   * 用戶狀態(tài)枚舉   */  public enum UserStatusEnum {    /**正常的*/    NORMAL,    /**禁用的*/    DISABLED,    /**已刪除的*/    DELETED;     /**     * 判斷參數(shù)合法性     */    public static boolean isValidName(String name) {      for (UserStatusEnum userStatusEnum : UserStatusEnum.values()) {        if (userStatusEnum.name().equals(name)) {          return true;        }      }      return false;    }  }     //省略getter、setter方法 } 

controller類

package com.zhuma.demo.web.user; import java.util.Date; import org.springframework.http.HttpStatus;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseStatus;import org.springframework.web.bind.annotation.RestController; import com.zhuma.demo.model.po.User; /** * @desc 用戶管理控制器 * * @author zhumaer * @since 6/20/2017 16:37 PM */@RestController@RequestMapping("/users")public class UserController {   @PostMapping  @ResponseStatus(HttpStatus.CREATED)  public User addUser(@Validated @RequestBody User user) {    user.setId(10000L);    user.setCreateTime(new Date());    return user;  } }  

“springboot validator枚舉值校驗功能的實現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI