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

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

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

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

簡(jiǎn)介

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

在任何時(shí)候,當(dāng)你要處理一個(gè)應(yīng)用程序的業(yè)務(wù)邏輯,數(shù)據(jù)校驗(yàn)是你必須要考慮和面對(duì)的事情。應(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 可以對(duì)原有的元數(shù)據(jù)信息進(jìn)行覆蓋和擴(kuò)展。在應(yīng)用程序中,通過使用 Bean Validation 或是你自己定義的 constraint,例如 @NotNull, @Max, @ZipCode, 就可以確保數(shù)據(jù)模型(JavaBean)的正確性。constraint 可以附加到字段,getter 方法,類或者接口上面。對(duì)于一些特定的需求,用戶可以很容易的開發(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ù)對(duì)象添加校驗(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(); }}

測(cè)試如下:

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)

新增和修改對(duì)于實(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ù)對(duì)象的校驗(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(); }}

測(cè)試如下:

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

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

雖然JSR303和springboot-validator 已經(jīng)提供了很多校驗(yàn)注解,但是當(dāng)面對(duì)復(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)重級(jí)別. 這個(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: 表示在對(duì)使用了該注解的類進(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,并且注冊(cè)到約束標(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對(duì)于@ListValue這個(gè)約束條件來說 是否是合法的。

在參數(shù)對(duì)象中使用@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;}

測(cè)試如下:

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)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
中文av在线全新| 日本成人在线视频网站| 欧美激情久久久久久久久久久| 五月国产精品| 日本综合视频| 97精品资源在线观看| 国产毛片精品| 精品一区二区三区在线观看视频 | 国产一区不卡| 国产一区2区| 日韩欧美一区二区三区在线视频 | 国产精品色在线网站| 国产精品亚洲综合久久| 国产精品1区| 高清av不卡| 久久精品青草| 视频在线观看国产精品| 美国三级日本三级久久99| 日韩有吗在线观看| 欧美精品97| 久久精选视频| 一区二区高清| 国产精品sss在线观看av| 在线看片国产福利你懂的| 91精品国产成人观看| 亚洲激情黄色| 国产精品亚洲综合色区韩国| 亚洲最新无码中文字幕久久| 欧美精品一线| 日韩精品欧美成人高清一区二区| 精品一区电影| 国产高清一区| 日本a口亚洲| 国产中文在线播放| 一本色道精品久久一区二区三区| 欧美综合社区国产| 伊人久久高清| 亚洲va久久| 日韩大片在线播放| 免费看的黄色欧美网站| 青青草91视频| 色婷婷久久久| 日本中文字幕视频一区| 日韩av二区| 蜜臀av一区二区在线免费观看| 国产精品成人一区二区网站软件| 99久久视频| 日韩1区2区3区| 日韩专区精品| 婷婷久久免费视频| 色婷婷狠狠五月综合天色拍| 亚洲综合五月| 色偷偷色偷偷色偷偷在线视频| 日韩中文字幕麻豆| 日韩av专区| 蜜桃视频免费观看一区| 国产成年精品| 亚洲精品系列| 久久婷婷丁香| 久久99久久久精品欧美| 国产亚洲亚洲| 国产不卡人人| 欧美自拍一区| 尤物在线精品| 日韩1区2区| 日韩国产在线观看一区| 欧美日韩在线观看视频小说| 国产精品15p| 另类av一区二区| 毛片在线网站| 国产欧美日韩视频在线| 欧美日韩日本国产亚洲在线| 成人日韩av| 日韩精品第一| 红桃视频国产一区| 日韩亚洲一区在线| 国产伦乱精品| 日韩欧美美女在线观看| 欧美日韩国产综合网| 福利欧美精品在线| 日韩av一区二区三区| 亚洲永久字幕| 久久蜜桃精品| 中文在线а√在线8| 国产亚洲欧美日韩在线观看一区二区| 激情综合自拍| 国产伦久视频在线观看| 久久精品97| 一区二区电影在线观看| 亚洲精品一区二区妖精| 六月婷婷综合| 精品视频在线一区二区在线| 日韩精品中文字幕一区二区| 99视频一区| 欧美影院三区| 香蕉成人av| 日韩成人精品一区| 老司机免费视频一区二区三区| 日韩中文一区二区| 久久福利影视| 亚洲午夜久久久久久尤物| av中文资源在线资源免费观看| 久久精品资源| 久久国产精品美女| 国产精品久久久免费| 国产亚洲精品美女久久 | 色综合www| 激情国产在线| 久久久久久久欧美精品| 午夜久久99| 在线国产一区二区| 久久精品国产99久久| 色老板在线视频一区二区| 日韩av有码| 欧美一级鲁丝片| 欧美片第1页| 成人va天堂| 欧美日韩一二三四| 中文在线一区| 视频在线观看一区| 亚洲v天堂v手机在线| 日本不卡的三区四区五区| 亚洲最大av| 日韩精品成人在线观看| 欧美另类中文字幕| 国产精品亚洲综合久久| 国产福利一区二区精品秒拍 | 中文在线а√在线8| 日韩深夜视频| 欧美亚洲国产一区| 99成人在线| 亚洲综合专区| 日韩二区三区在线观看| 欧美日韩1区| 精品在线网站观看| 激情亚洲影院在线观看| 午夜日韩av| 日韩精品免费一区二区夜夜嗨| 欧美私人啪啪vps| 精品中文在线| 亚洲成av在线| 尤物在线精品| 日韩精品久久久久久久软件91| 国产精品一区二区免费福利视频| 麻豆精品视频在线| 色在线中文字幕| 不卡在线一区| 亚洲一区欧美| 国产精品成人一区二区网站软件| 97精品中文字幕| 午夜精品免费| 日本aⅴ精品一区二区三区| 久久av资源| 欧美三级精品| 免费在线观看不卡| 国产精品theporn| 日韩网站中文字幕| 视频在线观看一区二区三区| 国产欧美一区二区精品久久久 | 久久av超碰| 激情亚洲影院在线观看| 亚洲一区二区动漫| 国产精品mm| 91成人精品| 国产精品第一| 免费精品国产的网站免费观看| 日韩中文字幕在线一区| 精品美女在线视频| 狠狠久久婷婷| 国产欧美日韩精品高清二区综合区| 在线人成日本视频| 蜜桃视频一区二区三区 | 日韩精品第一区| 久久av一区| 国内精品伊人| 麻豆91精品| 久久a爱视频| 国产亚洲毛片在线| 欧美国产另类| 中文一区二区| 电影91久久久| 综合一区av| 国产传媒av在线| 亚洲精品一二| 在线国产一区| 亚洲伊人av| 欧美日韩国产高清电影| 日韩精品a在线观看91| 麻豆视频在线观看免费网站黄| 免费观看在线综合色| 精品视频97| 丝袜美腿一区二区三区| 精品久久福利| 免费在线观看一区二区三区| 国产精品精品| 亚洲精品观看| 久久精品卡一| 美女久久久精品| 亚洲精品一级二级三级| 国产91精品对白在线播放|