一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - SpringBoot參數(shù)校驗(yàn)的最佳實(shí)戰(zhàn)教程

SpringBoot參數(shù)校驗(yàn)的最佳實(shí)戰(zhàn)教程

2021-12-02 13:28范閑 Java教程

開發(fā)過程中,后臺(tái)的參數(shù)校驗(yàn)是必不可少的,下面這篇文章主要給大家介紹了關(guān)于SpringBoot參數(shù)校驗(yàn)的最佳實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

我們這里使用hibernate-validator作為對象參數(shù)驗(yàn)證器,所以在正式介紹SpringBoot參數(shù)驗(yàn)證之前,需要先簡單了解一下hibernate-validator的使用。

hibernate-validator基本使用

引入依賴

?
1
2
3
4
5
6
7
8
9
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.17.Final</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
</dependency>

編寫需要驗(yàn)證對象

驗(yàn)證要求 person對象的用戶名不能為空,年齡在1-150歲之間。

?
1
2
3
4
5
6
7
8
9
10
@Data
public class Person {
 
    @NotBlank(message = "username must not be null")
    private String username;
 
    @Min(value = 1, message = "age must be >= 1")
    @Max(value = 150, message = "age must be < 150")
    private Integer age;
}

驗(yàn)證對象屬性是否符合要求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * 對象驗(yàn)證器
 */
public Validator validator() {
    ValidatorFactory validatorFactory =
            Validation
                    .byProvider(HibernateValidator.class)
                    .configure()
                    // 驗(yàn)證屬性時(shí),如果有一個(gè)驗(yàn)證不通過就返回,不需要驗(yàn)證所有屬性
                    .addProperty("hibernate.validator.fail_fast", "true")
                    .buildValidatorFactory();
    return validatorFactory.getValidator();
}
 
@Test
public void test() throws Exception {
    Person person = new Person();
    Set<ConstraintViolation<Person>> validate = validator().validate(person);
    validate.forEach(errorParam -> {
        System.out.println(errorParam.getMessage());
    });
}
  1. 我們只需要驗(yàn)證的對象實(shí)例即可完成對象驗(yàn)證,如果驗(yàn)證成功,那么返回一個(gè)空的集合,如果驗(yàn)證失敗,會(huì)返回具體的驗(yàn)證失敗的屬性信息。
  2. 我們輸出驗(yàn)證失敗的錯(cuò)誤信息如下:
?
1
username must not be null

驗(yàn)證規(guī)則

validator提供了大量的驗(yàn)證注解供我們使用,主要以下幾類:

SpringBoot參數(shù)校驗(yàn)的最佳實(shí)戰(zhàn)教程

空/非空驗(yàn)證

  1. @Null 元素必須為空
  2. @NotNull 元素不能為空,空字符串""是非空

以下所有驗(yàn)證規(guī)則都在元素非空的時(shí)候才會(huì)進(jìn)行驗(yàn)證,如果傳入的元素為空,驗(yàn)證都會(huì)通過。

bool

  1. @AssertTrue 元素必須為true
  2. @AssertFalse 元素必須為false

時(shí)間

  1. @Future 元素必須是未來的某個(gè)時(shí)間。
  2. @FutureOrPresent 元素必須是未來或者現(xiàn)在的某個(gè)時(shí)間。
  3. @Past 元素必須是過去的某個(gè)時(shí)間。
  4. @PastOrPresent 元素必須是過去或者現(xiàn)在的某個(gè)時(shí)間。

數(shù)學(xué)

數(shù)字類型可以是BigDecimal、BigInteger、CharSequence 、byte 、 short 、 int 、 long以及它們各自的包裝器類型

  1. @Digits 元素必須是該數(shù)字類型下可以被接受的數(shù)值范圍內(nèi)。
  2. @Negative 元素必須是負(fù)數(shù)
  3. @NegativeOrZero  元素必須小于等于0
  4. @Positive 元素必須大于0
  5. @PositiveOrZero 元素必須大于等于0
  6. @Max,@Min 元素的大小必須符合指定大小

字符串

  1. @Email 郵箱格式驗(yàn)證
  2. @NotBlack 驗(yàn)證字符串非空,空字符串""也屬于空
  3. @Pattern 字符串正則驗(yàn)證

模板正則

validator提供了字符串模板正則的注解,這里提供一份常用的正則表達(dá)式,大家可以直接作為常量工具類放到項(xiàng)目里使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public interface ValidatorPattern {
 
    /**
     * 正則表達(dá)式:驗(yàn)證用戶名
     * 1.長度在5-17
     * 2.由大寫小寫字母構(gòu)成
     */
    String REGEX_USERNAME = "^[a-zA-Z]\w{5,17}$";
 
    /**
     * 正則表達(dá)式:驗(yàn)證密碼
     * 密碼只能為 6 - 12位數(shù)字,字母及常用符號(hào)組成。
     */
    String REGEX_PASSWORD = "^(?=.*[a-zA-Z])(?=.*[0-9])[A-Za-z0-9._~!@#$^&*]{6,12}$";
 
    /**
     * 正則表達(dá)式:驗(yàn)證手機(jī)號(hào)
     */
    String REGEX_MOBILE = "^[1][34578]\d{9}$";
 
    /**
     * 正則表達(dá)式:驗(yàn)證郵箱
     */
    String REGEX_EMAIL = "^.+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$";
 
    /**
     * 正則表達(dá)式:驗(yàn)證漢字
     */
    String REGEX_CHINESE = "^[\u4e00-\u9fa5],*$";
 
    /**
     * 正則表達(dá)式:驗(yàn)證身份證
     */
    String REGEX_ID_CARD = "(^\d{18}$)|(^\d{15}$)";
 
    /**
     * 正則表達(dá)式:驗(yàn)證URL
     */
    String REGEX_URL = "http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
 
    /**
     * 正則表達(dá)式:驗(yàn)證IP地址
     */
    String REGEX_IP_ADDR = "(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)";
 
    /**
     * 車牌號(hào)正則
     */
    String LICENSE_NO = "^[京津滬渝冀豫云遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陜吉閩貴粵青藏川寧瓊使領(lǐng)A-Z][A-Z][A-Z0-9]{4,5}[A-Z0-9掛學(xué)警港澳]$";
 
    /**
     * 姓名校驗(yàn)
     * 1~15位
     * 姓名支持空格和中文的點(diǎn)
     */
    String NAME = "[\u4e00-\u9fa5\u00b7\sA-Za-z]{1,15}$";
 
    /**
     * 表情正則
     */
    String EMOJI = "[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]";
 
    /**
     * 數(shù)字正則
     */
    String NUMBER = "^[0-9]*$";
 
    /**
     * n位的數(shù)字
     */
    String N_NUMS = "^\d{n}$";
 
}

SpringBoot整合hibernate-validator

引入依賴

這個(gè)不再贅述,直接拷貝上文的依賴信息

配置hibernate-validator驗(yàn)證器對象

在配置類中加入hibernate-validator驗(yàn)證器對象

?
1
2
3
4
5
6
7
8
9
10
11
@Bean
@Primary
public Validator validator() {
    ValidatorFactory validatorFactory =
            Validation
                    .byProvider(HibernateValidator.class)
                    .configure()
                    .addProperty("hibernate.validator.fail_fast", "true")
                    .buildValidatorFactory();
    return validatorFactory.getValidator();
}

借助SpringMVC統(tǒng)一異常處理處理參數(shù)校驗(yàn)結(jié)果

配置好后,Spring會(huì)自動(dòng)幫助我們進(jìn)行參數(shù)驗(yàn)證,如果參數(shù)驗(yàn)證不通過,會(huì)拋出BindException異常,我們剛剛手動(dòng)驗(yàn)證時(shí)的Set<ConstraintViolation<Person>>通過該異常獲取。

我們這可以通過借助SpringMVC統(tǒng)一異常處理的能力處理這個(gè)異常

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Slf4j
@RestControllerAdvice
public class BaseExceptionHandler {
    /**
     * spring validation 自動(dòng)校驗(yàn)的參數(shù)異常
     *
     * @param e BindException
     * @return R<Void>
     */
    @ResponseStatus(org.springframework.http.HttpStatus.PAYMENT_REQUIRED)
    @ExceptionHandler(BindException.class)
    public R<Void> handler(BindException e) {
        String defaultMsg = e.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.joining(":"));
        log.warn(defaultMsg);
        return R.of(IRespCode.PARAMETERS_ANOMALIES.getCode(), e.getMessage());
    }
}

使用參數(shù)校驗(yàn)

我們只需要在校驗(yàn)參數(shù)的方法傳參上標(biāo)注@Valid或者@Validated都行

?
1
2
3
4
5
@PostMapping("register")
public R<Void> register(@Valid @RequestBody Person person) {
    // todo
    return R.ok();
}

分組校驗(yàn)

那么@Valid和@Validated有什么區(qū)別呢?

Validated比Valid多了一個(gè)屬性,這個(gè)屬性用于分組校驗(yàn)使用

?
1
2
3
4
5
public @interface Valid {
}
public @interface Validated {
    Class<?>[] value() default {};
}

啥叫分組校驗(yàn)?

就是一個(gè)實(shí)體類中的屬性,在不同的方法傳參中,方法的對屬性的要求不同。

比如說,Person類中有三個(gè)屬性,一個(gè)是用戶名稱,一個(gè)是郵箱,一個(gè)是年齡。

在注冊用戶接口中,用戶名稱,郵箱和年齡都不能為空,但是在更改用戶的信息接口中,用戶的年齡和郵箱都可以為空,但是用戶名稱不能為空。

這時(shí)候,我們就可以按照對屬性校驗(yàn)的要求進(jìn)行分組。

新建一個(gè)RegisterGroup分組,該分組只是一個(gè)空的接口,僅僅用于標(biāo)記該校驗(yàn)要求

?
1
2
public interface RegisterGroup {
}

對校驗(yàn)要求進(jìn)行分組

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Data
public class Person {
 
    @NotBlank(message = "username must not be null")
    private String username;
 
    @Min(value = 1, message = "age must be >= 1")
    @Max(value = 150, message = "age must be < 150")
    @NotNull(message = "age must not be null", groups = RegisterGroup.class)
    private Integer age;
 
    @Email(message = "email format error")
    @NotBlank(message = "email must not be null",groups = RegisterGroup.class)
    private String email;
}

方法調(diào)用時(shí),加入分組要求

?
1
2
3
4
5
@PostMapping("register")
public R<Void> register(@Validated(value = RegisterGroup.class) @RequestBody Person person) {
    // todo
    return R.ok();
}

這種方式其實(shí)不推薦使用,我在標(biāo)題的時(shí)候,也已經(jīng)標(biāo)記為“過時(shí)”,因?yàn)椋覀兺耆梢詾檫@兩個(gè)不同的接口創(chuàng)建兩個(gè)不同的實(shí)體類,而不是使用分組對校驗(yàn)要求進(jìn)行隔離,因?yàn)閷?shí)際生產(chǎn)環(huán)境中,分組可能有非常多個(gè),這會(huì)為我們的程序的可讀性埋下隱患,后期開發(fā)人員難以維護(hù),而且對于自動(dòng)生成API文檔也不友好。大家對于分組只需要了解即可,不建議在項(xiàng)目開發(fā)中使用。

總結(jié)

到此這篇關(guān)于SpringBoot參數(shù)校驗(yàn)的文章就介紹到這了,更多相關(guān)SpringBoot參數(shù)校驗(yàn)內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://juejin.cn/post/6999607085998538759

延伸 · 閱讀

精彩推薦
  • Java教程Java8中Stream使用的一個(gè)注意事項(xiàng)

    Java8中Stream使用的一個(gè)注意事項(xiàng)

    最近在工作中發(fā)現(xiàn)了對于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個(gè)非常重要的注意點(diǎn),所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7482021-02-04
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉(zhuǎn)換詳解

    xml與Java對象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程20個(gè)非常實(shí)用的Java程序代碼片段

    20個(gè)非常實(shí)用的Java程序代碼片段

    這篇文章主要為大家分享了20個(gè)非常實(shí)用的Java程序片段,對java開發(fā)項(xiàng)目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程升級(jí)IDEA后Lombok不能使用的解決方法

    升級(jí)IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級(jí),尋思已經(jīng)有好久沒有升過級(jí)了。升級(jí)完畢重啟之后,突然發(fā)現(xiàn)好多錯(cuò)誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java實(shí)現(xiàn)搶紅包功能

    Java實(shí)現(xiàn)搶紅包功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)搶紅包功能,采用多線程模擬多人同時(shí)搶紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙...

    littleschemer13532021-05-16
主站蜘蛛池模板: 日韩精品特黄毛片免费看 | 欧美精品综合一区二区三区 | 四虎海外影院 | 四虎传媒 | 波多野结衣一区 | 国产福利专区精品视频 | 青草国产| 处女呦呦| 天美传媒影视在线免费观看 | 天使萌痴汉在线中文字幕 | 999久久免费高清热精品 | 国产精品成人免费观看 | 5g影院天天| 欧美不卡一区二区三区 | 嫩草在线视频www免费观看 | 日本一卡二卡3卡四卡无卡网址 | 国产成人一级 | 国产自拍偷拍自拍 | 成人国产在线视频在线观看 | 好奇害死猫在线观看 | 羞羞漫画免费漫画页面在线看漫画秋蝉 | 欧美va免费大片 | 亚洲精品国产在线网站 | 我的男友是消防员在线观看 | 久久国产乱子伦免费精品 | 欧美一级在线播放 | 亚洲 欧美 制服 校园 动漫 | 万域之王动漫在线观看全集免费播放 | 窝窝午夜理伦影院 | 狠狠夜夜久久日日91av | 精品日本一区二区 | 国产v在线在线观看羞羞答答 | 亚洲精品一区制服丝袜 | 免费看成人毛片日本久久 | 国产高清在线精品一区二区 | 动漫精品午夜在线播放 | 亚洲美女啪啪 | 草女人逼 | 美女脱得一二净无内裤全身的照片 | 小寡妇好紧进去了好大看视频 | 微福利92合集 |