spring?boot?validation參數(shù)校驗(yàn)與分組嵌套各種類型及使用小結(jié)
寫在前面:
參數(shù)校驗(yàn)基本上是controller必做的事情,畢竟前端傳過來的一切都不可信。 但是每次if(StrUtil.isNotNull())啥的有時(shí)候多還難寫。validation可以簡化這一操作。
項(xiàng)目構(gòu)建
采用boot3,主要依賴為spring web 和validation
主要依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
項(xiàng)目結(jié)構(gòu)
問題展示
先來個(gè)簡單的案例
@RestController public class ValidationController { @GetMapping("/get") public String get(String name,String age){ System.out.println(name); System.out.println(age); return "ok"; } }
點(diǎn)擊這個(gè)就可以發(fā)送請(qǐng)求了
發(fā)送出去不會(huì)做任何校驗(yàn)
這個(gè)的處理我們可以選擇加上@RequestParam注解。@RequestParam默認(rèn)屬性require為true,就是必須要傳值,
public String get(@RequestParam String name,@RequestParam String age)
報(bào)錯(cuò)返回
封裝成實(shí)體類也是一樣的。
但是這樣只能做非null判斷,不能做復(fù)雜的判斷。在body里面的時(shí)候更加不會(huì)校驗(yàn)了
validation使用
那么validation又如何做到呢。
快速入門
需求:get請(qǐng)求中,name長度在2-10,age在10-100歲之間且都不為null。
@GetMapping("/get") public String get(@Length(max = 10,min = 2) String name, @Min(10)@Max(100) String age){ System.out.println("name = " + name); System.out.println("age = " + age); return "ok"; }
為null發(fā)送,好ok一點(diǎn)用沒有。
我查資料發(fā)現(xiàn)需要參數(shù)前面加上啟動(dòng)校驗(yàn)@Validated或者@Valid注解,但是無論我怎么放到都是沒有校驗(yàn)。全部無效。
我之前研究了半天,然后才發(fā)現(xiàn),如果想要這樣校驗(yàn)的話,需要在controller類上面加上@Validated且Valid都不行。
如果是實(shí)體類接收就不一樣了。直接在方法就可以了
注釋
到這里基本使用應(yīng)該就差不多知道了?,F(xiàn)在來進(jìn)行注解的學(xué)習(xí)。
注解通用屬性基本上都有的
屬性 | 描述 |
---|---|
message | 錯(cuò)誤返回描述 |
groups | 分組,可以進(jìn)行更加靈活的選擇。 |
payload |
無參注解,無必須傳的值
注解 | 限制 | 類型 |
---|---|---|
@Null | 限制只能為null | 接收任何類型,這個(gè)應(yīng)該用的比較少 |
@NotNull | 限制必須不為null | 接收任何類型 |
@AssertFalse | 限制必須為false | 支持的類型包括 boolean 和 Boolean。null 元素被視為有效。 |
@AssertTrue | 限制必須為true | 支持的類型包括 boolean 和 Boolean。null 元素被視為有效。 |
@Future | 限制必須是一個(gè)將來的日期 | 大部分的時(shí)間類如果Date、Calendar、Instant、LocalDate等。null 元素被視為有效 |
@Past | 限制必須是過去的時(shí)刻、日期或時(shí)間 | 和上面一樣 |
@PastOrPresent | 帶注釋的元素必須是過去或現(xiàn)在的時(shí)刻、日期或時(shí)間 | 同上 |
@NotEmpty | 帶批注的元素不得為 null和空 | CharSequence(計(jì)算字符序列的長度)Collection (集合大?。㎝ap (大?。?shù)組(計(jì)算數(shù)組長度) |
@NotBlank | 帶批注的元素不得且 null 必須至少包含一個(gè)非空格字符 | CharSequence |
@Positive | 帶注釋的元素必須是嚴(yán)格的正數(shù)(即 0 被視為無效值)。 | BigDecimal、BigInteger、byteintlong、 short及其floatdouble各自的包裝器 |
@PositiveOrZero | 正數(shù)或0 | 同上 |
大小注解,用于限值大小
注解 | 限制 | 類型 |
---|---|---|
@DecimalMax(value,inclusive) | 限制必須為一個(gè)不大于指定值的value數(shù)字,inclusive:指定指定的最小值是包含的還是排除的true為不包括最小值 | BigDecimal、BigInteger、CharSequence、byte、 shortintlong及其各自的包裝器,請(qǐng)注意, double 由于舍入錯(cuò)誤,不支持 (某些 float 提供程序可能會(huì)提供一些近似支持)。null 元素被視為有效。 |
@DecimalMin(value,inclusive) | 限制必須為一個(gè)不小于指定值的value數(shù)字,inclusive:最大值是否包括 | 同上 |
@Digits(integer,fraction) | 必須是接受范圍內(nèi)的數(shù)字,且整數(shù)部分的位數(shù)不能超過integer,小數(shù)部分的位數(shù)不能超過fraction | 同上 |
@Max(value) | 限制必須為一個(gè)不大于指定值的數(shù)字 | 同上 |
@Min(value) | 限制必須為一個(gè)不小于指定值的數(shù)字 | 同上 |
@Length(min = 6, max = 16) | 指定傳入的字符串的長度 | 字符串 |
@Size(max,min) | 限制字符長度必須在min到max之間 【不是數(shù)字】 | 同notempty,集合類數(shù)組和字符 |
@Range | 帶批注的元素必須在適當(dāng)?shù)姆秶鷥?nèi)。 | 應(yīng)用于數(shù)值或數(shù)值的字符串表示形式。 |
基于正則類型
注解 | 限制 | 類型 |
---|---|---|
@Pattern(value) | 限制必須符合指定的正則表達(dá)式 | CharSequence,null有效 |
驗(yàn)證注解的元素值是Email,可選值regexp,flags也可以通過正則表達(dá)式和flag指定自定義的email格式。因?yàn)槊總€(gè)人要求的郵箱可能格式也不一樣,如我可以通過regexp設(shè)置后綴必須為@qq.com | CharSequence,null有效 | |
@CreditCardNumber | 信用卡校驗(yàn) | 同上 |
@URL | 批注的字符串是否為 URL基于正則表達(dá)式的 。 | 同上 |
@UUID | 批注的字符序列是否為有效的 UUID,version指定版本variant變體,letterCase所需的字母大小寫 默認(rèn)情況下只有小寫有效,allowNil如果 nil UUID 有效 根據(jù)默認(rèn)值 nil UUID 00000000-0000-0000-0000-000000000000 有效,allowEmpty允許空字符串。默認(rèn)情況下不允許空字符串 |
腳本注解
@ScriptAssert
它根據(jù)批注元素計(jì)算腳本表達(dá)式。此約束可用于實(shí)現(xiàn)驗(yàn)證例程,腳本表達(dá)式可以用任何腳本或表達(dá)式語言編寫,在類路徑上可以找到 JSR 223 (“JavaTM 平臺(tái)腳本”)兼容引擎。下面的清單顯示了使用 JDK 附帶的 JavaScript 引擎的示例:
我看到的時(shí)候給我震驚了一下,他注解寫的啥??任何表達(dá)式語言??不過可能是我沒見過世面,或者是知識(shí)點(diǎn)用的少,java6就支持JavaScript。不過一般很少用吧。
下面是一個(gè)校驗(yàn)時(shí)間的腳本
@ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)") public class CalendarEvent { private Date startDate; private Date endDate; //... }
注意?。?!java11開始就移除了NashornScriptEngineFactory,所以11以上需要添加依賴才可以使用javascript需要新增
<dependency> <groupId>org.openjdk.nashorn</groupId> <artifactId>nashorn-core</artifactId> <version>15.4</version> </dependency>
沒有通過
修改時(shí)間通過了
Valid與Validated區(qū)別
Validated是Valid的加強(qiáng)版
使用范圍
經(jīng)過我的層層驗(yàn)證
- controller類上:
- 在controller類上只有使用validated,將開啟所有的路徑參數(shù)驗(yàn)證,對(duì)實(shí)體類(路徑和body)無效
- 方法上:
- 全部無效,無論是路徑還說body,2個(gè)注解都沒用。
- 入?yún)⑸希?/li>
- 只有在對(duì)body或者路徑參數(shù)實(shí)體類或者添加注解才有效,2個(gè)都有效,對(duì)單獨(dú)的類型無效
- 實(shí)體類的屬性上
- Valid有效,且路徑參數(shù)有效,body無效,body需要自己參數(shù)開啟,無論參數(shù)是否加驗(yàn)證注解
兩者是否能用于成員屬性(字段)上直接影響能否提供嵌套驗(yàn)證的功能。
分組
@Validated:提供了一個(gè)分組功能,可以在入?yún)Ⅱ?yàn)證時(shí),根據(jù)不同的分組采用不同的驗(yàn)證機(jī)制。沒有添加分組屬性時(shí),默認(rèn)驗(yàn)證沒有分組的驗(yàn)證屬性。Valid是不能進(jìn)行分組的,靈活性更差。
public class DemoQuery { @Length(max = 10, min = 2,groups = {Demo1.class, Demo2.class},message = "name長度不符合要求") private String name; @Min(value = 10,groups = {Demo1.class}) @Max(100) @NotNull private Integer age; }
@PostMapping("/post2") public String post2(@Validated({Demo2.class}) @RequestBody DemoQuery query, @NotNull String id) { System.out.println("name = " + query.getName()); System.out.println("age = " + query.getAge()); System.out.println("id = " + id); return "ok"; }
不通過
通過
改為demo1
嵌套驗(yàn)證
新增一個(gè)類
@Data public class NestedQuery { @NotNull private String id; @Valid @NotNull private DemoQuery querys; }
@GetMapping("/nested") public String nested(@Validated NestedQuery query, BindingResult bindingResult) { System.out.println("id = " + query.getId()); System.out.println("query = " + query.getQuerys()); System.out.println(bindingResult); return "ok"; }
發(fā)送返回的居然是ok,
但是在控制臺(tái),驗(yàn)證說出錯(cuò)了,說明嵌套的錯(cuò)誤不會(huì)直接返回,而是會(huì)記錄。需要自己處理一下。
如
Assert.isTrue(!bindingResult.hasErrors(),"參數(shù)錯(cuò)誤");
結(jié)束:收工,累死了。
到此這篇關(guān)于spring boot validation參數(shù)校驗(yàn)及分組嵌套各種類型及使用小結(jié)的文章就介紹到這了,更多相關(guān)spring boot validation參數(shù)校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot + validation 接口參數(shù)校驗(yàn)的思路詳解
- Spring?Boot集成validation實(shí)現(xiàn)參數(shù)校驗(yàn)功能
- SpringBoot使用Validation包進(jìn)行輸入?yún)?shù)校驗(yàn)
- springboot中使用Hibernate-Validation校驗(yàn)參數(shù)詳解
- SpringBoot使用Validation進(jìn)行參數(shù)校驗(yàn)的示例詳解
- spring-boot-starter-validation?校驗(yàn)參數(shù)的實(shí)現(xiàn)
- spring boot輸入數(shù)據(jù)校驗(yàn)(validation)的實(shí)現(xiàn)過程
- 從零到掌握Spring Boot Validation 接口校驗(yàn)的詳細(xì)過程
相關(guān)文章
Spring AOP日志框架實(shí)現(xiàn)過程圖解
這篇文章主要介紹了Spring AOP日志框架實(shí)現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09MapStruct實(shí)體間轉(zhuǎn)換的簡單用法
今天小編就為大家分享一篇關(guān)于MapStruct實(shí)體間轉(zhuǎn)換的簡單用法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-03-03Java實(shí)現(xiàn)SM3加密和驗(yàn)證的示例代碼
在商用密碼體系中,SM3主要用于數(shù)字簽名及驗(yàn)證、消息認(rèn)證碼生成及驗(yàn)證、隨機(jī)數(shù)生成等,其算法公開,本文給大家詳細(xì)介紹了使用Java實(shí)現(xiàn)SM3加密和驗(yàn)證,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2023-12-12Spring框架學(xué)習(xí)筆記之方法注解@Bean的使用
這篇文章主要給大家介紹了關(guān)于Spring框架學(xué)習(xí)筆記之方法注解@Bean使用的相關(guān)資料,這是一個(gè)我們很常用的注解,作用是指示一個(gè)方法生成一個(gè)由Spring管理的Bean,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12PageHelper插件實(shí)現(xiàn)一對(duì)多查詢時(shí)的分頁問題
這篇文章主要介紹了PageHelper插件實(shí)現(xiàn)一對(duì)多查詢時(shí)的分頁問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04