欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot實(shí)現(xiàn)請(qǐng)求參數(shù)驗(yàn)證的多種方法

 更新時(shí)間:2023年11月21日 11:33:39   作者:Aqoo  
在日常開發(fā)中,我們少不了需要對(duì)前端的請(qǐng)求參數(shù)的驗(yàn)證,Spring提供了多種方法來(lái)實(shí)現(xiàn)請(qǐng)求參數(shù)的驗(yàn)證,文中通過(guò)代碼示例給大家講解的非常詳細(xì),我們一起了解一下吧

注解

設(shè)置依賴

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

注解

以下是 validation-api中提供的可用的注解列表

注解含義
@Null驗(yàn)證對(duì)象必須為 null
@NotNull驗(yàn)證對(duì)象不為 null
@NotBlank驗(yàn)證字符串不能為空null或"",只能用于字符串驗(yàn)證
@NotEmpty驗(yàn)證對(duì)象不得為空,可用于Map和數(shù)組
@Pattern驗(yàn)證字符串是否滿足正則表達(dá)式
@AssertTrue驗(yàn)證 boolean 類型值為 true
@AssertFalse驗(yàn)證 boolean 類型值為 false
@Min(value)驗(yàn)證數(shù)字的大小是否大于等于指定的值
@Max(value)驗(yàn)證數(shù)字的大小是否小于等于指定的值
@DecimalMin(value)驗(yàn)證數(shù)字的大小是否大于等于指定的值,小數(shù)存在精度
@DecimalMax(value)驗(yàn)證數(shù)字的大小是否小于等于指定的值,小數(shù)存在精度
@Size(max, min)驗(yàn)證對(duì)象(字符串、集合、數(shù)組)長(zhǎng)度是否在指定范圍之內(nèi)
@Digits(integer, fraction)驗(yàn)證數(shù)字是否符合指定格式
@Pattern(value)驗(yàn)證字符串是否符合正則表達(dá)式的規(guī)則
@ParameterScriptAssert可以在方法參數(shù)級(jí)別上執(zhí)行腳本驗(yàn)證,以驗(yàn)證傳遞給方法的參數(shù)是否符合指定的條件。該注解可以與 JSR 223 兼容的腳本引擎一起使用,例如 JavaScript、Groovy、Python 等。- script:腳本表達(dá)式,用于執(zhí)行參數(shù)驗(yàn)證。該表達(dá)式應(yīng)該返回一個(gè) boolean 類型的值,表示驗(yàn)證是否通過(guò)。- lang:腳本語(yǔ)言的名稱,默認(rèn)為 "groovy"。
@Email驗(yàn)證字符串是否符合電子郵件地址的格式。
@Future驗(yàn)證一個(gè)日期或時(shí)間是否在當(dāng)前時(shí)間之后。
@FutureOrPresent驗(yàn)證一個(gè)日期或時(shí)間是否在當(dāng)前時(shí)間之后或等于當(dāng)前時(shí)間。
@past驗(yàn)證一個(gè)日期或時(shí)間是否在當(dāng)前時(shí)間之前。
@PastOrPresent驗(yàn)證一個(gè)日期或時(shí)間是否在當(dāng)前時(shí)間之前或等于當(dāng)前時(shí)間。
@Positive驗(yàn)證數(shù)字是否是正整數(shù),0無(wú)效
@PositiveOrZero驗(yàn)證數(shù)字是否是正整數(shù)
@Negative驗(yàn)證數(shù)字是否是負(fù)整數(shù),0無(wú)效
@NegativeOrZero驗(yàn)證數(shù)字是否是負(fù)整數(shù)

以上大致就是validation-api默認(rèn)提供的參數(shù)驗(yàn)證注解。示例如下:

另外需要注意的是,在每個(gè)注解中基本上都一個(gè)分組屬性:Class<?>[] groups() default { };

其作用就是對(duì)對(duì)象屬性分組,用于在不同的場(chǎng)景下支持不同的參數(shù)驗(yàn)證。我們來(lái)舉一個(gè)列子:

比如我們新增和更新數(shù)據(jù)的操作一般都用同一個(gè)對(duì)象來(lái)接收前端傳入?yún)?shù)。那么新增時(shí)的Id可能為空,而編輯時(shí)的Id不能為空,我們對(duì)參數(shù)的驗(yàn)證規(guī)則是不一樣的。那么怎么實(shí)現(xiàn)呢?這里就需要用到我們的groups()了。代碼如下:

    @RequestMapping("create")
    @ResponseBody
    public String create(@RequestBody @Validated(Create.class) User user) {
        return "create success";
    }

    @RequestMapping("update")
    @ResponseBody
    public String update(@RequestBody @Validated(Update.class) User user) {
        return "update success";
    }

    @Data
    public static class User {
        @NotBlank(message = "id不能為空", groups = {Update.class})
        private String id;

        @NotNull(message = "用戶名不能為空", groups = {Create.class, Update.class})
        private String username;

        @NotNull(message = "密碼不能為空")
        private String password;
    }

    public interface Create {
    }

    public interface Update {
    }

根據(jù)需求,我們?cè)?User 的 id 屬性上標(biāo)記上 groups = {Update.class},在 username 屬性上標(biāo)記 groups = {Create.class, Update.class}。則表明我們對(duì)id只在 @Validated(Update.class) 時(shí)驗(yàn)證id的值;username 則在 @Validated(Update.class) 或者 @Validated(Create.class) 時(shí)都需要驗(yàn)證。

自定義驗(yàn)證

首先,定義一個(gè)自定義注解,例如 @ValidEnum:

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ValidEnumValidator.class)
public @interface ValidEnum {
    String message() default "無(wú)效的枚舉值";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    Class<? extends Enum<?>> value();
}

@ValidEnum 注解用于驗(yàn)證一個(gè)枚舉類型的值是否在指定的枚舉類型中,使用 ValidEnumValidator 類對(duì)其進(jìn)行驗(yàn)證。

接下來(lái),定義一個(gè) ValidEnumValidator 類,實(shí)現(xiàn)對(duì) @ValidEnum 注解的驗(yàn)證邏輯:

public class ValidEnumValidator implements ConstraintValidator<ValidEnum, Object> {
    private Set<String> validValues = new HashSet<>();

    @Override
    public void initialize(ValidEnum constraintAnnotation) {
        Class<? extends Enum<?>> enumClass = constraintAnnotation.value();
        Enum<?>[] enumValues = enumClass.getEnumConstants();
        for (Enum<?> enumValue : enumValues) {
            validValues.add(enumValue.name());
        }
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        return validValues.contains(value.toString());
    }
}

ValidEnumValidator 類實(shí)現(xiàn)了 ConstraintValidator 接口,并重寫了 initialize() 和 isValid() 兩個(gè)方法。initialize() 方法用于初始化驗(yàn)證器,獲取枚舉類型的所有枚舉值;isValid() 方法用于實(shí)現(xiàn)驗(yàn)證邏輯,判斷枚舉值是否在指定的枚舉類型中。

最后,在使用 @Validated 注解的 Controller 中,對(duì)請(qǐng)求參數(shù)使用自定義的 @ValidEnum 注解進(jìn)行驗(yàn)證

@RestController
@Validated
public class UserController {
    @GetMapping("/user")
    public void getUser(@RequestParam @ValidEnum(value = Gender.class) String gender) {
        // 處理請(qǐng)求
    }
}

@ValidEnum 注解用于驗(yàn)證 gender 參數(shù)是否在 Gender 枚舉類型中。如果 gender 參數(shù)的值不在 Gender 枚舉類型中,則會(huì)拋出 ConstraintViolationException 異常,并帶有指定的錯(cuò)誤消息。

需要注意的是,自定義的 Bean Validation 注解需要使用 @Constraint 注解進(jìn)行標(biāo)注,并指定對(duì)應(yīng)的驗(yàn)證器類。

在驗(yàn)證器類中,需要實(shí)現(xiàn) ConstraintValidator 接口,并實(shí)現(xiàn) initialize() 和 isValid() 方法。在使用自定義注解進(jìn)行參數(shù)驗(yàn)證時(shí),需要在對(duì)應(yīng)的 Controller 中使用 @Validated 注解進(jìn)行標(biāo)注。

有趣的歷史

大家可以看到spring-boot-starter-validation 中依賴的包是 jakarta.validation-api,其命名空間屬于jakarta。jakarta.validation-api 實(shí)現(xiàn)的規(guī)范依舊是JSR380,熟悉的小伙伴可能知道其實(shí)以前用的是 javax.validation-api。可是為什么現(xiàn)在會(huì)是jakarta.validation-api 呢,而不是 javax.validation-api?這中間其實(shí)涉及到了太多的商業(yè)上的博弈。有興趣的大家可以自己去了解下,有時(shí)間單獨(dú)出一篇介紹。

以上就是springboot實(shí)現(xiàn)請(qǐng)求參數(shù)驗(yàn)證的多種方法的詳細(xì)內(nèi)容,更多關(guān)于springboot校驗(yàn)參數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java淺析枚舉類的使用

    Java淺析枚舉類的使用

    枚舉類型可以取代以往常量的定義方式,即將常量封裝在類或接口中。此外,枚舉類型還提供了安全檢查功能。本文就來(lái)和大家講講Java中枚舉類的用法,需要的可以參考一下
    2022-07-07
  • 詳解Java中使用externds關(guān)鍵字繼承類的用法

    詳解Java中使用externds關(guān)鍵字繼承類的用法

    子類使用extends繼承父類是Java面向?qū)ο缶幊讨械幕A(chǔ)知識(shí),這里我們就來(lái)詳解Java中使用externds關(guān)鍵字繼承類的用法,需要的朋友可以參考下
    2016-07-07
  • Mybatis通過(guò)Spring完成代理類注入的流程分析

    Mybatis通過(guò)Spring完成代理類注入的流程分析

    這篇文章主要介紹了Mybatis通過(guò)Spring完成代理類注入的流程分析,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • Java中List轉(zhuǎn)Map List實(shí)現(xiàn)的幾種姿勢(shì)

    Java中List轉(zhuǎn)Map List實(shí)現(xiàn)的幾種姿勢(shì)

    本文主要介紹了Java中List轉(zhuǎn)Map List實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Spring?Boot2?整合連接?Redis的操作方法

    Spring?Boot2?整合連接?Redis的操作方法

    在Spring?Boot中,通過(guò)RedisTemplate可以方便地對(duì)Redis進(jìn)行操作,包括設(shè)置和獲取數(shù)據(jù),文章詳細(xì)介紹了如何配置RedisTemplate,創(chuàng)建RedisConfig類進(jìn)行自定義配置,并通過(guò)Controller訪問(wèn)Redis數(shù)據(jù)庫(kù),感興趣的朋友一起看看吧
    2025-02-02
  • java實(shí)現(xiàn)轉(zhuǎn)圈打印矩陣算法

    java實(shí)現(xiàn)轉(zhuǎn)圈打印矩陣算法

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)轉(zhuǎn)圈打印矩陣算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • Java Map 在put值時(shí)value值不被覆蓋的解決辦法

    Java Map 在put值時(shí)value值不被覆蓋的解決辦法

    這篇文章主要介紹了Java Map 在put值時(shí)value值不被覆蓋的解決辦法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-04-04
  • java?list和map切割分段的實(shí)現(xiàn)及多線程應(yīng)用案例

    java?list和map切割分段的實(shí)現(xiàn)及多線程應(yīng)用案例

    這篇文章主要為大家介紹了java?list和map切割分段的實(shí)現(xiàn)及多線程應(yīng)用案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Java自動(dòng)添加重寫的toString方法詳解

    Java自動(dòng)添加重寫的toString方法詳解

    在本篇文章里小編給大家整理了關(guān)于Java自動(dòng)添加重寫的toString方法總結(jié),需要的朋友們學(xué)習(xí)下。
    2019-07-07
  • Java編程Retry重試機(jī)制實(shí)例詳解

    Java編程Retry重試機(jī)制實(shí)例詳解

    這篇文章主要介紹了Java編程Retry重試機(jī)制實(shí)例詳解,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02

最新評(píng)論