springboot validator枚舉值校驗功能實現(xiàn)
這篇文章主要介紹了springboot validator枚舉值校驗功能實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
一、前言
在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)方案
上面提到的一組常量值,我們第一反應(yīng)應(yīng)該是定義一個枚舉類,盡量不要放在一個統(tǒng)一的constants類下,這樣當系統(tǒng)一旦龐大起來,常量是很難維護和查找的,所以前期代碼也應(yīng)該有一些規(guī)范性約束,這里我們約定一組常量值時使用枚舉,并把該枚舉類放在對應(yīng)的類對象里(以上述所說的用戶功能為例,我們應(yīng)該把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; } }
校驗結(jié)果
最后
好啦,一個簡單的校驗枚舉值的注解功能完成了。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:spring為java.util.Properties類型的屬性進行賦值過程解析
欄 目:Java
下一篇:JDK13.0.1安裝與環(huán)境變量的配置教程圖文詳解(Win10平臺為例)
本文標題:springboot validator枚舉值校驗功能實現(xiàn)
本文地址:http://mengdiqiu.com.cn/a1/Java/8728.html
您可能感興趣的文章
- 01-10Springboot中@Value的使用詳解
- 01-10springboot實現(xiàn)文件上傳步驟解析
- 01-10springboot jta atomikos實現(xiàn)分布式事物管理
- 01-10SpringBoot使用RabbitMQ延時隊列(小白必備)
- 01-10如何基于SpringBoot部署外部Tomcat過程解析
- 01-10springboot集成fastDfs過程代碼實例
- 01-10SPRINGBOOT讀取PROPERTIES配置文件數(shù)據(jù)過程詳解
- 01-10springboot 配置DRUID數(shù)據(jù)源的方法實例分析
- 01-10springboot2.0使用Hikari連接池的方法(替換druid)
- 01-10springboot單元測試兩種方法實例詳解


閱讀排行
本欄相關(guān)
- 01-10Java實現(xiàn)動態(tài)模擬時鐘
- 01-10Springboot中@Value的使用詳解
- 01-10JavaWeb實現(xiàn)郵件發(fā)送功能
- 01-10利用Java實現(xiàn)復(fù)制Excel工作表功能
- 01-10Java實現(xiàn)動態(tài)數(shù)字時鐘
- 01-10java基于poi導(dǎo)出excel透視表代碼實例
- 01-10java實現(xiàn)液晶數(shù)字字體顯示當前時間
- 01-10基于Java驗證jwt token代碼實例
- 01-10Java動態(tài)顯示當前日期和時間
- 01-10淺談Java中真的只有值傳遞么
隨機閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10delphi制作wav文件的方法
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實例總結(jié)
- 01-11ajax實現(xiàn)頁面的局部加載
- 08-05織夢dedecms什么時候用欄目交叉功能?