Spring Boot使用@Valid進行表單校驗

有些時候我們在項目中,會對增加/修改進行字段的校驗,比如年齡一定的在一個合理的範圍內。比如不能超過1000歲。不能是-1歲。
名字也會在合理的範圍內,如果都是中國人的話先不說不能有字母了,起碼不會超過20個字。
還有別的亂七八糟的,比如郵箱一定是郵箱格式的。身份證號是18位,手機號1開頭,11位數等等等等。這些實現很簡單。
如果不規範的可能直接前端校驗後端不管了。這種常規下好像不會出問題,但是其實很不推薦。萬一有人繞開這個前端直接調接口啥的呢。
稍微不規範一點的就是後端寫大量代碼,一個屬性一個屬性去判斷。反正這樣倒也能增加代碼行數。指不定一個十幾個字段的表單,能寫個上百行校驗的代碼。但是可讀性極差,而且其實雖然是無腦if,但是也挺費時間的。
其實這種表單校驗是有現成的工具的。

導入依賴

其實這裏有兩種方式導入依賴。我們如果是使用Spring boot搭建項目的話,一定會引入web模塊(如果和前端沒交互也不存在表單校驗啦)。而2.0.5.RELEASE版本的web包已經有了這個功能(感興趣的同學可以自己去看你所在的web版本有沒有這個表單校驗的依賴。)。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.0.5.RELEASE</version>
        </dependency>

當然瞭如果你的項目沒有使用web模塊的這個版本,也可以單獨去引入表單校驗的依賴包:

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

其實web2.0.5版本也是引入了這個依賴包的。如下圖:



實際上我們導包的時候就能看出來,這個註解就是
javax.validation裏的。


使用

其實這個的使用方法就是在實體類上加校驗。
注意這裏兩個依賴包裏都有校驗的註解。感興趣的可以看一下。而且使用方法也略有不同。我這裏簡單把註解截圖,差不多都可以見名知意的:




其實這些校驗有一些是重複的。然後比如size是校驗list的長度。Length是校驗字符串的長度,min/max校驗數值的大小,字符串長度啥的(校驗長度要用在length註解裏),非空校驗啥的。這裏就不一一說了。我先附上個demo展示下如何使用:



因爲這個都是我爲了展示效果寫的校驗,所以直接以截圖的形式來展示了。大家可以注意我使用這麼多註解是來自於兩個包。然後message是不通過時候的提示。也可以不給寫。
而這個校驗的結果有一個專門的BindingResult對象來接收的。
我先展示下使用效果:

這裏我直接返回所有的error信息了。實際上大家可以酌情返回或者處理後展示。有一說一這個可讀性還是挺差的。



返回值是這樣的:
[
    {
        "codes": [
            "Max.userEntity.age",
            "Max.age",
            "Max.java.lang.Integer",
            "Max"
        ],
        "arguments": [
            {
                "codes": [
                    "userEntity.age",
                    "age"
                ],
                "arguments": null,
                "defaultMessage": "age",
                "code": "age"
            },
            100
        ],
        "defaultMessage": "年齡不能超過100",
        "objectName": "userEntity",
        "field": "age",
        "rejectedValue": 102,
        "bindingFailure": false,
        "code": "Max"
    },
    {
        "codes": [
            "Range.userEntity.level",
            "Range.level",
            "Range.java.lang.Integer",
            "Range"
        ],
        "arguments": [
            {
                "codes": [
                    "userEntity.level",
                    "level"
                ],
                "arguments": null,
                "defaultMessage": "level",
                "code": "level"
            },
            5,
            1
        ],
        "defaultMessage": "等級要在1和5之間",
        "objectName": "userEntity",
        "field": "level",
        "rejectedValue": 7,
        "bindingFailure": false,
        "code": "Range"
    },
    {
        "codes": [
            "Email.userEntity.email",
            "Email.email",
            "Email.java.lang.String",
            "Email"
        ],
        "arguments": [
            {
                "codes": [
                    "userEntity.email",
                    "email"
                ],
                "arguments": null,
                "defaultMessage": "email",
                "code": "email"
            },
            [],
            {
                "defaultMessage": ".*",
                "arguments": null,
                "codes": [
                    ".*"
                ]
            }
        ],
        "defaultMessage": "不是一個合法的電子郵件地址",
        "objectName": "userEntity",
        "field": "email",
        "rejectedValue": "1112",
        "bindingFailure": false,
        "code": "Email"
    },
    {
        "codes": [
            "AssertTrue.userEntity.flag",
            "AssertTrue.flag",
            "AssertTrue.java.lang.Boolean",
            "AssertTrue"
        ],
        "arguments": [
            {
                "codes": [
                    "userEntity.flag",
                    "flag"
                ],
                "arguments": null,
                "defaultMessage": "flag",
                "code": "flag"
            }
        ],
        "defaultMessage": "用戶不存在",
        "objectName": "userEntity",
        "field": "flag",
        "rejectedValue": false,
        "bindingFailure": false,
        "code": "AssertTrue"
    }
]

因爲我完美的做到了每一項都錯了,所以大家別誤會是返回的總的信息。這裏的其實都是錯誤信息。大家可以處理後返回,比如把所有的defaultMessage彙總返回。或者每次只返回第一項然後一次一次讓用戶修改啥的都行。

這個工具的用法就這樣,其實真的很簡單,但是如果沒有的話自己寫校驗還是挺麻煩的。再複雜一點的比如手機號身份證號也可以用正則來校驗。感覺能滿足大多數的校驗需求了。
本篇筆記就記到這裏,如果稍微幫到你了記得點個喜歡點個關注。也祝大家工作順順利利,每天get一個小技巧~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章