最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot中使用JSR-303實(shí)現(xiàn)請求參數(shù)校驗

 更新時間:2023年10月26日 16:07:35   作者:Miaow.Y.Hu  
這篇文章主要介紹了Spring Boot中使用JSR-303實(shí)現(xiàn)請求參數(shù)校驗,JSR-303校驗我們一般都是對Java的實(shí)體類對象進(jìn)行校驗,主要檢驗JSR-303是Java中的一個規(guī)范,用于實(shí)現(xiàn)請求參數(shù)校驗在我們的實(shí)體類對象的屬性上,感興趣的朋友跟隨小編一起看看吧

JSR-303是Java中的一個規(guī)范,用于實(shí)現(xiàn)請求參數(shù)校驗。它定義了一組注解,可以應(yīng)用于JavaBean的字段上,用于驗證輸入?yún)?shù)的合法性。下面是一些常用的JSR-303注解及其介紹:

@NotNull:用于驗證字段值不能為null。
@NotEmpty:用于驗證字符串字段不能為空。
@NotBlank:用于驗證字符串字段不能為空,并且長度必須大于0。
@Min:用于驗證數(shù)字字段的最小值。
@Max:用于驗證數(shù)字字段的最大值。
@Size:用于驗證字符串、集合或數(shù)組字段的長度或大小。
@Pattern:用于驗證字符串字段是否匹配指定的正則表達(dá)式。
@Email:用于驗證字符串字段是否符合Email格式。
@Range:用于驗證數(shù)字字段的取值范圍。
@Valid:用于嵌套驗證,可以對對象中的字段進(jìn)行遞歸驗證。
其他如下圖所示:

通過在JavaBean的字段上添加這些注解,可以在接收請求參數(shù)時進(jìn)行自動校驗。如果校驗失敗,可以通過異常處理機(jī)制來處理校驗錯誤。

需要注意的是,JSR-303只提供了基本的驗證注解,如果需要更復(fù)雜的校驗邏輯,可以自定義注解或使用第三方庫,如Hibernate Validator等。
Hibernate Validator附加的constraint:

至于我們?yōu)樯妒褂肑SR-303來校驗我們的參數(shù),主要是為了解決我們在實(shí)際開發(fā)過程中,前后端的參數(shù)校驗導(dǎo)致的問題。比如:

  • 我們依靠前端框架解決參數(shù)校驗,但是缺少服務(wù)器的參數(shù)校驗,這種情況常見于需要同時進(jìn)行開發(fā)前后端的時候,雖然程序的正常使用不會有問題,到那時開發(fā)者會忽略非正常的操作,比如繞過前端程序,直接模擬客戶端請求,這樣就繞過了我們對前端預(yù)設(shè)的各種限制,直擊我們后端的數(shù)據(jù)訪問接口,進(jìn)而使得我們的后端系統(tǒng)存在嚴(yán)重的安全隱患。
  • 大量的利用if/else語句嵌套實(shí)現(xiàn),使得我們的校驗邏輯晦澀難懂,并不利于我們對整個系統(tǒng)的維護(hù)。

JSR的定義標(biāo)準(zhǔn)

驗證觸發(fā)時機(jī):

  • JSR-303校驗標(biāo)準(zhǔn)定義了兩個觸發(fā)校驗的時機(jī):
    • 在對象被持久化之前(例如,保存到數(shù)據(jù)庫之前)。
    • 在對象被修改之后(例如,更新數(shù)據(jù)庫中的記錄后)。
  • 校驗約束注解:JSR-303標(biāo)準(zhǔn)提供了一組注解,可以用于對Java對象的屬性進(jìn)行校驗。這些注解包括但不限于@NotNull、@NotEmpty@Min、@Max@Size、@Pattern@Email 等。開發(fā)人員可以根據(jù)需求選擇適當(dāng)?shù)淖⒔鈦矶x校驗規(guī)則。
  • 校驗組:JSR-303允許將校驗規(guī)則分組,以便在特定情況下選擇性地執(zhí)行校驗。開發(fā)人員可以為每個校驗注解指定一個或多個校驗組,然后在校驗時選擇要執(zhí)行的校驗組。
  • 嵌套校驗:JSR-303允許對復(fù)雜對象進(jìn)行嵌套校驗,即在校驗一個對象時,也會對其關(guān)聯(lián)的其他對象進(jìn)行校驗。這樣可以確保整個對象圖的完整性和合法性。
  • 自定義校驗:JSR-303還允許開發(fā)人員定義自己的校驗注解和校驗器,以滿足特定的校驗需求。通過實(shí)現(xiàn) ConstraintValidator 接口來自定義校驗器,并在自定義注解中使用該校驗器。
  • 校驗結(jié)果:JSR-303校驗結(jié)果以校驗異常的形式返回。當(dāng)校驗失敗時,會拋出 ConstraintViolationException 異常,其中包含了校驗失敗的詳細(xì)信息,例如校驗失敗的屬性、校驗失敗的值、校驗錯誤消息等。

接下來我們將圍繞我們在Spring Boot的實(shí)體類中,使用JSR-303校驗。值得注意的是,JSR-303校驗我們一般都是對Java的實(shí)體類對象進(jìn)行校驗,主要檢驗在我們的實(shí)體類對象的屬性上。

還是利用我們==>上一篇 <===的相關(guān)依賴文件,這篇我就不在重復(fù)導(dǎo)入相關(guān)依賴文件了。本篇著重文件主要正在User類和UserController,所用的依賴pom.xml文件和application.properties均與上篇一樣,就不在重復(fù)描述了。

PS: 你可以看到我在依賴中均采用了lombok,但是我卻并未使用這個玩意,原因在于,我使用了lombok

@ApiModel(description = "用戶實(shí)體")
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;
    public User(Long id, String name, Integer age, String email) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.email = email;
    }
    public User() {
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", email='" + email + '\'' +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id) && Objects.equals(name, user.name) && Objects.equals(age, user.age) && Objects.equals(email, user.email);
    }
    @Override
    public int hashCode() {
        return Objects.hash(id, name, age, email);
    }
}
@Api(tags = "用戶管理")
@RestController
@RequestMapping(value = "/users")     // 通過這里配置使下面的映射都在/users下
public class UserController {
    // 創(chuàng)建線程安全的Map,模擬users信息的存儲
    static Map<Long, User> users = Collections.synchronizedMap(new HashMap<>());
    @GetMapping("/")
    @ApiOperation(value = "獲取用戶列表")
    public List<User> getUserList() {
        List<User> r = new ArrayList<>(users.values());
        return r;
    }
    @PostMapping("/")
    @ApiOperation(value = "創(chuàng)建用戶", notes = "根據(jù)User對象創(chuàng)建用戶")
    public String postUser(@Valid @RequestBody User user) {
        users.put(user.getId(), user);
        return "success";
    }
    @GetMapping("/{id}")
    @ApiOperation(value = "獲取用戶詳細(xì)信息", notes = "根據(jù)url的id來獲取用戶詳細(xì)信息")
    public User getUser(@PathVariable Long id) {
        return users.get(id);
    }
    @PutMapping("/{id}")
    @ApiImplicitParam(paramType = "path", dataType = "Long", name = "id", value = "用戶編號", required = true, example = "1")
    @ApiOperation(value = "更新用戶詳細(xì)信息", notes = "根據(jù)url的id來指定更新對象,并根據(jù)傳過來的user信息來更新用戶詳細(xì)信息")
    public String putUser(@PathVariable Long id, @RequestBody User user) {
        User u = users.get(id);
        u.setName(user.getName());
        u.setAge(user.getAge());
        users.put(id, u);
        return "success";
    }
    @DeleteMapping("/{id}")
    @ApiOperation(value = "刪除用戶", notes = "根據(jù)url的id來指定刪除對象")
    public String deleteUser(@PathVariable Long id) {
        users.remove(id);
        return "success";
    }
}

接下來啟動項目,當(dāng)然啟動類還是需要加:
@EnableSwagger2Doc這個注解

之后,我們可以通過使用相關(guān)工具比如Postman等測試工具發(fā)起,也可以使用curl發(fā)起,比如:

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"
}'

得到相關(guān)信息:

{
    "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": "個數(shù)必須在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/"
}

其中返回名稱的各參數(shù)含義如下:

timestamp:請求時間
status:HTTP返回的狀態(tài)碼,這里返回400,即:請求無效、錯誤的請求,通常參數(shù)校驗不通過均為400
error:HTTP返回的錯誤描述,這里對應(yīng)的就是400狀態(tài)的錯誤描述:Bad Request
errors:具體錯誤原因,是一個數(shù)組類型;因為錯誤校驗可能存在多個字段的錯誤,比如這里因為定義了兩個參數(shù)不能為Null,所以存在兩條錯誤記錄信息
message:概要錯誤消息,返回內(nèi)容中很容易可以知道,這里的錯誤原因是對user對象的校驗失敗,其中錯誤數(shù)量為2,而具體的錯誤信息就定義在上面的errors數(shù)組中
path:請求路徑

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

瀏覽器訪問:
http://localhost:8080/swagger-ui.html

我們可以看到校驗的部分限制。

到此這篇關(guān)于Spring Boot中使用JSR-303實(shí)現(xiàn)請求參數(shù)校驗的文章就介紹到這了,更多相關(guān)springboot JSR-303請求參數(shù)校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決IDEA service層跳轉(zhuǎn)實(shí)現(xiàn)類的快捷圖標(biāo)消失問題

    解決IDEA service層跳轉(zhuǎn)實(shí)現(xiàn)類的快捷圖標(biāo)消失問題

    這篇文章主要介紹了解決IDEA service層跳轉(zhuǎn)實(shí)現(xiàn)類的快捷圖標(biāo)消失問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Java中String的split切割字符串方法實(shí)例及擴(kuò)展

    Java中String的split切割字符串方法實(shí)例及擴(kuò)展

    最近在項目中遇到一個小問題,一個字符串分割成一個數(shù)組,下面這篇文章主要給大家介紹了關(guān)于Java中String的split切割字符串方法的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • SpringBoot2入門自動配置原理及源碼分析

    SpringBoot2入門自動配置原理及源碼分析

    這篇文章主要為大家介紹了SpringBoot2入門自動配置原理及源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Java數(shù)組拷貝的四種常用方式總結(jié)

    Java數(shù)組拷貝的四種常用方式總結(jié)

    數(shù)組是 Java 最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)之一,而 數(shù)組的拷貝(復(fù)制) 是開發(fā)中經(jīng)常遇到的需求,Java 提供了多種數(shù)組復(fù)制方式,每種方式都有自己的特點(diǎn)和適用場景,本篇文章將系統(tǒng)總結(jié) Java 中 數(shù)組拷貝的 4 種常用方式,需要的朋友可以參考下
    2025-12-12
  • Java數(shù)據(jù)結(jié)構(gòu)之二叉查找樹的實(shí)現(xiàn)

    Java數(shù)據(jù)結(jié)構(gòu)之二叉查找樹的實(shí)現(xiàn)

    二叉查找樹(亦稱二叉搜索樹、二叉排序樹)是一棵二叉樹,且各結(jié)點(diǎn)關(guān)鍵詞互異,其中根序列按其關(guān)鍵詞遞增排列。本文將通過示例詳細(xì)講解二叉查找樹,感興趣的可以了解一下
    2022-03-03
  • Java 常量字符串過長的解決方法

    Java 常量字符串過長的解決方法

    這篇文章主要介紹了Java 常量字符串過長的解決方法,常量字符串過長會提示報錯,下面我們就一起來了解一下解決方法
    2021-04-04
  • Java Volatile關(guān)鍵字你真的了解嗎

    Java Volatile關(guān)鍵字你真的了解嗎

    這篇文章主要為大家介紹了Java Volatile關(guān)鍵字,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • Java中正則表達(dá)式的使用和詳解(下)

    Java中正則表達(dá)式的使用和詳解(下)

    這篇文章主要介紹了Java正則表達(dá)式的使用和詳解(下)的相關(guān)資料,包括常用正則表達(dá)式和正則表達(dá)式語法,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧
    2017-04-04
  • java中HashMap的七種遍歷方式小結(jié)

    java中HashMap的七種遍歷方式小結(jié)

    本文主要介紹了java中HashMap的七種遍歷方式小結(jié),包括迭代器,For Each,Lambda,Streams API等,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • java實(shí)現(xiàn)后臺數(shù)據(jù)顯示在前端

    java實(shí)現(xiàn)后臺數(shù)據(jù)顯示在前端

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)后臺數(shù)據(jù)顯示在前端,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02

最新評論

安塞县| 长沙市| 娱乐| 攀枝花市| 卓资县| 丹凤县| 塔河县| 弥勒县| 兴山县| 花垣县| 文登市| 齐齐哈尔市| 永川市| 胶州市| 明星| 本溪市| 黑水县| 清河县| 新丰县| 龙海市| 渑池县| 健康| 汉川市| 衡水市| 郸城县| 大连市| 二手房| 边坝县| 轮台县| 海安县| 临夏市| 阜新| 威宁| 南澳县| 云林县| 雷波县| 凌海市| 隆回县| 深水埗区| 永寿县| 巴林右旗|