中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Spring Boot怎么實現請求參數校驗

發布時間:2022-03-03 16:06:51 來源:億速云 閱讀:193 作者:iii 欄目:web開發

這篇文章主要介紹了Spring Boot怎么實現請求參數校驗的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Spring Boot怎么實現請求參數校驗文章都會有所收獲,下面我們一起來看看吧。

JSR-303

在開始動手實踐之前,我們先了解一下接下來我們將使用的一項標準規范:JSR-303

什么是JSR?

JSR是Java Specification Requests的縮寫,意思是Java 規范提案。是指向JCP(Java Community Process)提出新增一個標準化技術規范的正式請求。任何人都可以提交JSR,以向Java平臺增添新的API和服務。JSR已成為Java界的一個重要標準。

JSR-303定義的是什么標準?

JSR-303 是JAVA EE 6 中的一項子規范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的參考實現 . Hibernate Validator 提供了 JSR 303 規范中所有內置 constraint 的實現,除此之外還有一些附加的 constraint。

Bean Validation中內置的constraint

Spring Boot怎么實現請求參數校驗

Hibernate Validator附加的constraint

Spring Boot怎么實現請求參數校驗

在JSR-303的標準之下,我們可以通過上面這些注解,優雅的定義各個請求參數的校驗。更多關于JSR的內容可以參與官方文檔或參考資料中的引文[1]。

動手實踐

已經了解了JSR-303之后,接下來我們就來嘗試一下,基于此規范如何實現參數的校驗!

準備工作

讀者可以拿任何一個使用Spring Boot 2.x構建的提供RESTful API的項目作為基礎。也可以使用Spring Boot 2.x基礎教程:使用Swagger2構建強大的API文檔中構建的實驗工程作為基礎,您可以通過下面倉庫中的chapter2-2目錄取得:

  • Github:https://github.com/dyc87112/SpringBoot-Learning/tree/2.x

  • Gitee:https://gitee.com/didispace/SpringBoot-Learning/tree/2.x

當然,您也可以根據前文再構建一個作為復習,也是完全沒有問題的。

快速入門

我們先來做一個簡單的例子,比如:定義字段不能為Null。只需要兩步

第一步:在要校驗的字段上添加上@NotNull注解,具體如下:

@Data
@ApiModel(description="用戶實體")
public class User {

    @ApiModelProperty("用戶編號")
    private Long id;

    @NotNull
    @ApiModelProperty("用戶姓名")
    private String name;

    @NotNull
    @ApiModelProperty("用戶年齡")
    private Integer age;

}

第二步:在需要校驗的參數實體前添加@Valid注解,具體如下:

@PostMapping("/")
@ApiOperation(value = "創建用戶", notes = "根據User對象創建用戶")
public String postUser(@Valid @RequestBody User user) {
    users.put(user.getId(), user);
    return "success";
}

完成上面配置之后,啟動應用,并用POST請求訪問localhost:8080/users/接口,body使用一個空對象,{}。你可以用Postman等測試工具發起,也可以使用curl發起,比如這樣:

curl -X POST \
  http://localhost:8080/users/ \
  -H 'Content-Type: application/json' \
  -H 'Postman-Token: 72745d04-caa5-44a1-be84-ba9c115f4dfb' \
  -H 'cache-control: no-cache' \
  -d '{
    
}'

不出意外,你可以得到如下結果:

{
    "timestamp": "2019-10-05T05:45:19.221+0000",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "NotNull.user.age",
                "NotNull.age",
                "NotNull.java.lang.Integer",
                "NotNull"
            ],
            "arguments": [
                {
                    "codes": [
                        "user.age",
                        "age"
                    ],
                    "arguments": null,
                    "defaultMessage": "age",
                    "code": "age"
                }
            ],
            "defaultMessage": "不能為null",
            "objectName": "user",
            "field": "age",
            "rejectedValue": null,
            "bindingFailure": false,
            "code": "NotNull"
        },
        {
            "codes": [
                "NotNull.user.name",
                "NotNull.name",
                "NotNull.java.lang.String",
                "NotNull"
            ],
            "arguments": [
                {
                    "codes": [
                        "user.name",
                        "name"
                    ],
                    "arguments": null,
                    "defaultMessage": "name",
                    "code": "name"
                }
            ],
            "defaultMessage": "不能為null",
            "objectName": "user",
            "field": "name",
            "rejectedValue": null,
            "bindingFailure": false,
            "code": "NotNull"
        }
    ],
    "message": "Validation failed for object='user'. Error count: 2",
    "path": "/users/"
}

其中返回內容的各參數含義如下:

  • timestamp:請求時間

  • status:HTTP返回的狀態碼,這里返回400,即:請求無效、錯誤的請求,通常參數校驗不通過均為400

  • error:HTTP返回的錯誤描述,這里對應的就是400狀態的錯誤描述:Bad Request

  • errors:具體錯誤原因,是一個數組類型;因為錯誤校驗可能存在多個字段的錯誤,比如這里因為定義了兩個參數不能為Null,所以存在兩條錯誤記錄信息

  • message:概要錯誤消息,返回內容中很容易可以知道,這里的錯誤原因是對user對象的校驗失敗,其中錯誤數量為2,而具體的錯誤信息就定義在上面的errors數組中

  • path:請求路徑

請求的調用端在拿到這個規范化的錯誤信息之后,就可以方便的解析并作出對應的措施以完成自己的業務邏輯了。

嘗試一些其他校驗

在完成了上面的例子之后,我們還可以增加一些校驗規則,比如:校驗字符串的長度、校驗數字的大小、校驗字符串格式是否為郵箱等。下面我們就來定義一些復雜的校驗定義,比如:

@Data
@ApiModel(description="用戶實體")
public class User {

    @ApiModelProperty("用戶編號")
    private Long id;

    @NotNull
    @Size(min = 2, max = 5)
    @ApiModelProperty("用戶姓名")
    private String name;

    @NotNull
    @Max(100)
    @Min(10)
    @ApiModelProperty("用戶年齡")
    private Integer age;

    @NotNull
    @Email
    @ApiModelProperty("用戶郵箱")
    private String email;

}

發起一個可以出發name、age、email都校驗不通過的請求,比如下面這樣:

curl -X POST \
  http://localhost:8080/users/ \
  -H 'Content-Type: application/json' \
  -H 'Postman-Token: 114db0f0-bdce-4ba5-baf6-01e5104a68a3' \
  -H 'cache-control: no-cache' \
  -d '{
    "name": "abcdefg",
    "age": 8,
    "email": "aaaa"
}'

我們將得到如下的錯誤返回:

{
    "timestamp": "2019-10-05T06:24:30.518+0000",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "Size.user.name",
                "Size.name",
                "Size.java.lang.String",
                "Size"
            ],
            "arguments": [
                {
                    "codes": [
                        "user.name",
                        "name"
                    ],
                    "arguments": null,
                    "defaultMessage": "name",
                    "code": "name"
                },
                5,
                2
            ],
            "defaultMessage": "個數必須在2和5之間",
            "objectName": "user",
            "field": "name",
            "rejectedValue": "abcdefg",
            "bindingFailure": false,
            "code": "Size"
        },
        {
            "codes": [
                "Min.user.age",
                "Min.age",
                "Min.java.lang.Integer",
                "Min"
            ],
            "arguments": [
                {
                    "codes": [
                        "user.age",
                        "age"
                    ],
                    "arguments": null,
                    "defaultMessage": "age",
                    "code": "age"
                },
                10
            ],
            "defaultMessage": "最小不能小于10",
            "objectName": "user",
            "field": "age",
            "rejectedValue": 8,
            "bindingFailure": false,
            "code": "Min"
        },
        {
            "codes": [
                "Email.user.email",
                "Email.email",
                "Email.java.lang.String",
                "Email"
            ],
            "arguments": [
                {
                    "codes": [
                        "user.email",
                        "email"
                    ],
                    "arguments": null,
                    "defaultMessage": "email",
                    "code": "email"
                },
                [],
                {
                    "defaultMessage": ".*",
                    "codes": [
                        ".*"
                    ],
                    "arguments": null
                }
            ],
            "defaultMessage": "不是一個合法的電子郵件地址",
            "objectName": "user",
            "field": "email",
            "rejectedValue": "aaaa",
            "bindingFailure": false,
            "code": "Email"
        }
    ],
    "message": "Validation failed for object='user'. Error count: 3",
    "path": "/users/"
}

從errors數組中的各個錯誤明細中,知道各個字段的defaultMessage,可以看到很清晰的錯誤描述。

Swagger文檔中的體現

可能有讀者會問了,我的接口中是定了這么多。上一篇教程中,不是還教了如何自動生成文檔么,那么對于參數的校驗邏輯該如何描述呢?

這里要分兩種情況,Swagger自身對JSR-303有一定的支持,但是支持的并那么完善,并沒有覆蓋所有的注解的。

比如,上面我們使用的注解是可以自動生成的,啟動上面我們的實驗工程,然后訪問http://localhost:8080/swagger-ui.html,在Models不是,我們可以看到如下圖所示的內容:

其中:name和age字段相比上一篇教程中的文檔描述,多了一些關于校驗相關的說明;而email字段則沒有體現相關校驗說明。目前,Swagger共支持以下幾個注解:@NotNull、@Max、@Min、@Size、@Pattern。在實際開發過程中,我們需要分情況來處理,對于Swagger支自動生成的可以利用原生支持來產生,如果有部分字段無法產生,則可以在@ApiModelProperty注解的描述中他,添加相應的校驗說明,以便于使用方查看。

番外:也許你會有這些疑問

當請求參數校驗出現錯誤信息的時候,錯誤格式可以修改嗎?

答案是肯定的。這里的錯誤信息實際上由Spring Boot的異常處理機制統一組織并返回的,我們將在后面的教程中詳細介紹,Spring Boot是如何統一處理異常返回以及我們該如何定時異常返回。

spring-boot-starter-validation是必須的嗎?

有讀者之前問過,看到很多教程都寫了還要引入spring-boot-starter-validation依賴,這個依賴到底是否需要?(本篇中并沒有引入)

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

其實,只需要仔細看一下spring-boot-starter-validation依賴主要是為了引入了什么,再根據當前自己使用的Spring Boot版本來判斷即可。實際上,spring-boot-starter-validation依賴主要是為了引入下面這個依賴:

<dependency>
   <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.14.Final</version>
    <scope>compile</scope>
</dependency>

我們可以看看當前工程的依賴中是否有它,就可以判斷是否還需要額外引入。在Spring Boot 2.1版本中,該依然其實已經包含在了spring-boot-starter-web依賴中,并不需要額外引入,所以您在本文中找不到這一步。

關于“Spring Boot怎么實現請求參數校驗”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Spring Boot怎么實現請求參數校驗”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

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

AI

闽侯县| 梁山县| 沁源县| 石门县| 元朗区| 时尚| 南漳县| 长岛县| 武鸣县| 邹城市| 松潘县| 焦作市| 浦北县| 七台河市| 通渭县| 双牌县| 平谷区| 紫金县| 河间市| 邻水| 贡山| 连城县| 阜南县| 乌鲁木齐市| 乌什县| 库车县| 河北区| 准格尔旗| 恩施市| 仙桃市| 开远市| 边坝县| 铜鼓县| 台北县| 郎溪县| 宜昌市| 武冈市| 阳原县| 鄢陵县| 寻乌县| 莱阳市|