日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Spring Boot利用JSR303實(shí)現(xiàn)參數(shù)驗(yàn)證的方法實(shí)例

瀏覽:130日期:2023-05-16 18:04:49

簡介

JSR-303 是 JAVA EE 6 中的一項(xiàng)子規(guī)范,叫做 Bean Validation。

在任何時(shí)候,當(dāng)你要處理一個(gè)應(yīng)用程序的業(yè)務(wù)邏輯,數(shù)據(jù)校驗(yàn)是你必須要考慮和面對的事情。應(yīng)用程序必須通過某種手段來確保輸入進(jìn)來的數(shù)據(jù)從語義上來講是正確的。在通常的情況下,應(yīng)用程序是分層的,不同的層由不同的開發(fā)人員來完成。很多時(shí)候同樣的數(shù)據(jù)驗(yàn)證邏輯會(huì)出現(xiàn)在不同的層,這樣就會(huì)導(dǎo)致代碼冗余和一些管理的問題,比如說語義的一致性等。為了避免這樣的情況發(fā)生,最好是將驗(yàn)證邏輯與相應(yīng)的域模型進(jìn)行綁定。

Bean Validation 為 JavaBean 驗(yàn)證定義了相應(yīng)的元數(shù)據(jù)模型和 API。缺省的元數(shù)據(jù)是 Java Annotations,通過使用 XML 可以對原有的元數(shù)據(jù)信息進(jìn)行覆蓋和擴(kuò)展。在應(yīng)用程序中,通過使用 Bean Validation 或是你自己定義的 constraint,例如 @NotNull, @Max, @ZipCode, 就可以確保數(shù)據(jù)模型(JavaBean)的正確性。constraint 可以附加到字段,getter 方法,類或者接口上面。對于一些特定的需求,用戶可以很容易的開發(fā)定制化的 constraint。Bean Validation 是一個(gè)運(yùn)行時(shí)的數(shù)據(jù)驗(yàn)證框架,在驗(yàn)證之后驗(yàn)證的錯(cuò)誤信息會(huì)被馬上返回。

Bean Validation 規(guī)范內(nèi)嵌的約束注解

Spring Boot利用JSR303實(shí)現(xiàn)參數(shù)驗(yàn)證的方法實(shí)例

實(shí)例

基本應(yīng)用

引入依賴

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId></dependency>

給參數(shù)對象添加校驗(yàn)注解

@Datapublic class User { private Integer id; @NotBlank(message = '用戶名不能為空') private String username; @Pattern(regexp = '^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$', message = '密碼必須為8~16個(gè)字母和數(shù)字組合') private String password; @Email private String email; private Integer gender;}

Controller 中需要校驗(yàn)的參數(shù)Bean前添加 @Valid 開啟校驗(yàn)功能,緊跟在校驗(yàn)的Bean后添加一個(gè)BindingResult,BindingResult封裝了前面Bean的校驗(yàn)結(jié)果。

@RestController@RequestMapping('/user')public class UserController { @PostMapping('') public Result save (@Valid User user , BindingResult bindingResult) { if (bindingResult.hasErrors()) { Map<String , String> map = new HashMap<>(); bindingResult.getFieldErrors().forEach( (item) -> { String message = item.getDefaultMessage(); String field = item.getField(); map.put( field , message ); } ); return Result.build( 400 , '非法參數(shù) !' , map); } return Result.ok(); }}

測試如下:

Spring Boot利用JSR303實(shí)現(xiàn)參數(shù)驗(yàn)證的方法實(shí)例

異常的統(tǒng)一處理

參數(shù)校驗(yàn)不通過時(shí),會(huì)拋出 BingBindException 異常,可以在統(tǒng)一異常處理中,做統(tǒng)一處理,這樣就不用在每個(gè)需要參數(shù)校驗(yàn)的地方都用 BindingResult 獲取校驗(yàn)結(jié)果了。

@Slf4j@RestControllerAdvice(basePackages = 'com.itwolfed.controller')public class GlobalExceptionControllerAdvice { @ExceptionHandler(value= {MethodArgumentNotValidException.class , BindException.class}) public Result handleVaildException(Exception e){ BindingResult bindingResult = null; if (e instanceof MethodArgumentNotValidException) { bindingResult = ((MethodArgumentNotValidException)e).getBindingResult(); } else if (e instanceof BindException) { bindingResult = ((BindException)e).getBindingResult(); } Map<String,String> errorMap = new HashMap<>(16); bindingResult.getFieldErrors().forEach((fieldError)-> errorMap.put(fieldError.getField(),fieldError.getDefaultMessage()) ); return Result.build(400 , '非法參數(shù) !' , errorMap); }}

分組解決校驗(yàn)

新增和修改對于實(shí)體的校驗(yàn)規(guī)則是不同的,例如id是自增的時(shí)候,新增時(shí)id要為空,修改則必須不為空;新增和修改,若用的恰好又是同一種實(shí)體,那就需要用到分組校驗(yàn)。

校驗(yàn)注解都有一個(gè)groups屬性,可以將校驗(yàn)注解分組,我們看下@NotNull的源碼:

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)@Repeatable(List.class)@Documented@Constraint(validatedBy = { })public @interface NotNull { String message() default '{javax.validation.constraints.NotNull.message}'; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Documented @interface List { NotNull[] value(); }}

從源碼可以看出 groups 是一個(gè)Class<?>類型的數(shù)組,那么就可以創(chuàng)建一個(gè)Groups.

public class Groups { public interface Add{} public interface Update{}}

給參數(shù)對象的校驗(yàn)注解添加分組

@Datapublic class User { @Null(message = '新增不需要指定id' , groups = Groups.Add.class) @NotNull(message = '修改需要指定id' , groups = Groups.Update.class) private Integer id; @NotBlank(message = '用戶名不能為空') @NotNull private String username; @Pattern(regexp = '^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$', message = '密碼必須為8~16個(gè)字母和數(shù)字組合') private String password; @Email private String email; private Integer gender;}

Controller 中原先的@Valid不能指定分組 ,需要替換成@Validated

@RestController@RequestMapping('/user')public class UserController { @PostMapping('') public Result save (@Validated(Groups.Add.class) User user) { return Result.ok(); }}

測試如下:

Spring Boot利用JSR303實(shí)現(xiàn)參數(shù)驗(yàn)證的方法實(shí)例

自定義校驗(yàn)注解

雖然JSR303和springboot-validator 已經(jīng)提供了很多校驗(yàn)注解,但是當(dāng)面對復(fù)雜參數(shù)校驗(yàn)時(shí),還是不能滿足我們的要求,這時(shí)候我們就需要 自定義校驗(yàn)注解。

例如User中的gender,用 1代表男 2代表女,我們自定義一個(gè)校驗(yàn)注解@ListValue,指定取值只能1和2。

創(chuàng)建約束規(guī)則

@Documented@Constraint(validatedBy = { ListValueConstraintValidator.class })@Target({ METHOD, FIELD, ANNOTATION_TYPE })@Retention(RUNTIME)public @interface ListValue { String message() default ''; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; int[] vals() default { };}

一個(gè)標(biāo)注(annotation) 是通過@interface關(guān)鍵字來定義的. 這個(gè)標(biāo)注中的屬性是聲明成類似方法 的樣式的. 根據(jù)Bean Validation API 規(guī)范的要求:

message屬性, 這個(gè)屬性被用來定義默認(rèn)得消息模版, 當(dāng)這個(gè)約束條件被驗(yàn)證失敗的時(shí)候,通過 此屬性來輸出錯(cuò)誤信息。 groups 屬性, 用于指定這個(gè)約束條件屬于哪(些)個(gè)校驗(yàn)組. 這個(gè)的默認(rèn)值必須是Class<?>類型數(shù)組。 payload 屬性, Bean Validation API 的使用者可以通過此屬性來給約束條件指定嚴(yán)重級別. 這個(gè)屬性并不被API自身所使用。

除了這三個(gè)強(qiáng)制性要求的屬性(message, groups 和 payload) 之外, 我們還添 加了一個(gè)屬性用來指定所要求的值. 此屬性的名稱vals在annotation的定義中比較特 殊, 如果只有這個(gè)屬性被賦值了的話, 那么, 在使用此annotation到時(shí)候可以忽略此屬性名稱.

另外, 我們還給這個(gè)annotation標(biāo)注了一些元標(biāo)注( meta annotatioins):

@Target({ METHOD, FIELD, ANNOTATION_TYPE }): 表示此注解可以被用在方法, 字段或者 annotation聲明上。 @Retention(RUNTIME): 表示這個(gè)標(biāo)注信息是在運(yùn)行期通過反射被讀取的. @Constraint(validatedBy = ListValueConstraintValidator.class): 指明使用哪個(gè)校驗(yàn)器(類) 去校驗(yàn)使用了此標(biāo)注的元素. @Documented: 表示在對使用了該注解的類進(jìn)行javadoc操作到時(shí)候, 這個(gè)標(biāo)注會(huì)被添加到 javadoc當(dāng)中.

創(chuàng)建約束校驗(yàn)器

import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;import java.util.HashSet;import java.util.Set;public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> { private Set<Integer> set = new HashSet<>(); /** * 初始化方法 */ @Override public void initialize(ListValue constraintAnnotation) { int[] vals = constraintAnnotation.vals(); for (int val : vals) { set.add(val); } } /** * 判斷是否校驗(yàn)成功 * * @param value 需要校驗(yàn)的值 * @param context * @return */ @Override public boolean isValid(Integer value, ConstraintValidatorContext context) { return set.contains(value); }}

ListValueConstraintValidator定義了兩個(gè)泛型參數(shù), 第一個(gè)是這個(gè)校驗(yàn)器所服務(wù)到標(biāo)注類型(在我們的例子中即ListValue), 第二個(gè)這個(gè)校驗(yàn)器所支持到被校驗(yàn)元素的類型 (即Integer)。

如果一個(gè)約束標(biāo)注支持多種類型的被校驗(yàn)元素的話, 那么需要為每個(gè)所支持的類型定義一個(gè)ConstraintValidator,并且注冊到約束標(biāo)注中。

這個(gè)驗(yàn)證器的實(shí)現(xiàn)就很平常了, initialize() 方法傳進(jìn)來一個(gè)所要驗(yàn)證的標(biāo)注類型的實(shí)例, 在本 例中, 我們通過此實(shí)例來獲取其vals屬性的值,并將其保存為Set集合中供下一步使 用。

isValid()是實(shí)現(xiàn)真正的校驗(yàn)邏輯的地方, 判斷一個(gè)給定的int對于@ListValue這個(gè)約束條件來說 是否是合法的。

在參數(shù)對象中使用@ListValue注解。

@Datapublic class User { @Null(message = '新增不需要指定id' , groups = Groups.Add.class) @NotNull(message = '修改需要指定id' , groups = Groups.Update.class) private Integer id; @NotBlank(message = '用戶名不能為空') @NotNull private String username; @Pattern(regexp = '^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$', message = '密碼必須為8~16個(gè)字母和數(shù)字組合') private String password; @Email private String email; @ListValue( message = '性別應(yīng)指定相應(yīng)的值' , vals = {1,2} , groups = {Groups.Add.class , Groups.Update.class}) private Integer gender;}

測試如下:

Spring Boot利用JSR303實(shí)現(xiàn)參數(shù)驗(yàn)證的方法實(shí)例

源碼地址

https://github.com/gf-huanchupk/SpringBootLearning

參考

https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/index.html https://docs.jboss.org/hibernate/validator/4.3/reference/zh-CN/pdf/hibernate validator reference.pdf

總結(jié)

到此這篇關(guān)于Spring Boot利用JSR303實(shí)現(xiàn)參數(shù)驗(yàn)證的文章就介紹到這了,更多相關(guān)Spring Boot用JSR303參數(shù)驗(yàn)證內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
黄色av日韩| 欧美/亚洲一区| 亚洲一区二区日韩| 国产66精品| 色爱av综合网| 视频一区在线播放| 国产精品极品| 久久精品免费一区二区三区| 亚洲午夜免费| 精品视频国内| 亚洲精品一区二区妖精| 日韩有码av| 久久91视频| 黄色日韩在线| 国产精品视频一区二区三区四蜜臂 | 亚洲精品美女91| 国产精品一国产精品| 秋霞影院一区二区三区| 亚洲精品自拍| av日韩中文| 亚洲欧美日本国产| 成人国产综合| 欧美精品九九| 久久国产精品免费一区二区三区| 国产999精品在线观看| 久久一二三区| 成人一区而且| 蜜臀国产一区二区三区在线播放| 久久一区欧美| 久久亚洲精品伦理| 亚洲精品永久免费视频| 亚洲欧美一级| 亚洲高清毛片| 国产精品极品在线观看| 亚洲精品动态| 免费成人在线观看| 欧美精品1区| 亚洲最新无码中文字幕久久| 欧美日韩免费观看一区=区三区 | 欧美国产日韩电影| 久久久蜜桃一区二区人| 伊人成人网在线看| 欧美日一区二区在线观看| 日韩伦理在线一区| 午夜久久久久| 国产欧美日韩视频在线| 日韩欧美不卡| 亚洲2区在线| 狠狠躁少妇一区二区三区| 另类av一区二区| 国产精品久久久久久久久久妞妞| 久久九九国产| 国产精品久久久亚洲一区| 亚州av乱码久久精品蜜桃| 国产视频一区二| 欧美日韩精品在线一区| 日本视频一区二区| 亚洲午夜在线| 欧美激情三区| 久色成人在线| 成人一区而且| 日韩毛片网站| 久久理论电影| 国产欧美日韩精品一区二区三区| 婷婷激情久久| 亚洲精品少妇| 色爱av综合网| 国产三级精品三级在线观看国产| 99免费精品| 国产精品视频一区二区三区| 亚洲成人精选| 久久69成人| 亚洲不卡视频| 亚洲午夜91| 精品99在线| 亚洲精品少妇| 精品一区毛片| 国产亚洲一区| 日韩中文字幕区一区有砖一区| 国产成人77亚洲精品www| 美女久久一区| 亚洲www啪成人一区二区| 国产精品xxx在线观看| 香蕉视频成人在线观看| 中文字幕在线高清| 青青草国产成人99久久| 日韩视频一区二区三区在线播放免费观看| 精品视频一二| 青青在线精品| 国产精品免费看| av高清不卡| 国产精品毛片视频| 亚洲一区欧美| 91久久久精品国产| www在线观看黄色| 欧美一级网站| 日韩影院在线观看| 欧美成人精品| 日韩免费一区| 色婷婷综合网| 国产黄色一区| 日韩福利视频导航| 亚洲欧美在线专区| 免费成人在线影院| av不卡在线| 亚洲黄色在线| 9色精品在线| 欧美成人午夜| 青青久久av| 中国字幕a在线看韩国电影| 国产日韩中文在线中文字幕 | 99热免费精品| 欧美成人国产| 精品一区欧美| 亚洲精品极品少妇16p| 亚洲高清毛片| 久久在线免费| 欧美 日韩 国产精品免费观看| 欧产日产国产精品视频| 成人片免费看| 欧美天堂视频| 国产欧洲在线| av资源新版天堂在线| 成人在线黄色| 欧洲av不卡| 亚洲成人va| 91精品国产自产在线观看永久∴| 蜜臀国产一区| 视频福利一区| 欧美特黄一级| 在线观看一区| 欧美亚洲免费| 久久99国产精品视频| 精品国产乱码久久久| а√天堂中文在线资源8| 久久久久蜜桃| 欧美日韩国产一区二区三区不卡 | 日本va欧美va瓶| 欧美午夜三级| 国产欧美亚洲一区| 九九久久国产| 亚洲黄色网址| 亚洲免费黄色| 日产欧产美韩系列久久99| 国产精品草草| 亚洲综合电影| 激情欧美一区二区三区| av亚洲在线观看| 在线看片一区| 欧美经典一区| 久久国产亚洲精品| 亚洲婷婷丁香| 免费在线成人| 久久人人97超碰国产公开结果| 亚洲免费黄色| 日韩av不卡在线观看| 国产成人精品一区二区三区免费| 91精品国产成人观看| 国产欧美一区二区三区米奇| 欧美啪啪一区| 激情丁香综合| 国产免费av一区二区三区| 亚洲婷婷免费| 久久不卡日韩美女| 国产日韩专区| 久久uomeier| 日韩二区在线观看| 亚洲五月婷婷| 精品视频一区二区三区在线观看| 亚洲精品888| 国产极品模特精品一二| 午夜精品婷婷| 国产精品麻豆久久| 日韩精品成人在线观看| 日本在线精品| 麻豆精品在线视频| 免费在线欧美视频| 欧美成人a交片免费看| 久久精品99国产精品| 亚洲激情五月| 国际精品欧美精品| 日欧美一区二区| 激情婷婷综合| 久久影院午夜精品| av成人国产| 免费久久精品| 精品在线网站观看| 久久亚洲风情| 中文字幕在线免费观看视频| 综合一区av| 丝袜美腿诱惑一区二区三区| 热久久国产精品| 日韩毛片视频| 日韩动漫一区| 欧美+亚洲+精品+三区| 精品中国亚洲| 五月国产精品| 1024精品一区二区三区| 国产精品久久久亚洲一区| 久久不射网站|