国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java代碼瘦身,巧用 @Valid,@Validated 的分組校驗和嵌套檢驗,實現(xiàn)高階參數(shù)校驗操作

這篇具有很好參考價值的文章主要介紹了Java代碼瘦身,巧用 @Valid,@Validated 的分組校驗和嵌套檢驗,實現(xiàn)高階參數(shù)校驗操作。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Java代碼瘦身,巧用 @Valid,@Validated 的分組校驗和嵌套檢驗,實現(xiàn)高階參數(shù)校驗操作

導讀

? ? ? ? 在 JavaEE 項目中, RestFull 層接收參數(shù)首先要對一些字段的格式進行校驗,以防止所有查詢都落到數(shù)據(jù)庫,這也是一種合理的限流手段。以前基本上都是用 if...else...,這樣的代碼太啰嗦,除了使用策略模式進行優(yōu)化,今天介紹一下校驗注解@Valid,@Validated和@PathVariable,不僅可以減輕代碼量,還加強了代碼的易讀性。


正文

1. @Valid 和 @Validated 區(qū)別

????????先講一下這兩個注解:@Valid與@Validated都是用來校驗接收參數(shù)的,如果不使用注解校驗參數(shù),那么就需要在業(yè)務代碼中逐一校驗,這樣會增加很多的工作量,并且代碼不優(yōu)美。

????????剛開始接觸的時候多半會被弄混,實際上二者差距還是挺大的。根據(jù)自己的項目經(jīng)驗,@Validated和@Valid各有特點,可以聯(lián)合使用。

Java代碼瘦身,巧用 @Valid,@Validated 的分組校驗和嵌套檢驗,實現(xiàn)高階參數(shù)校驗操作

  • 提供者

javax.validation.Valid:使用 Hibernate validation 的時候使用,是 JSR-303 規(guī)范標準注解支持。如果你是 springboot 項目,那么可以不用單獨引入依賴了,因為它就存在于最核心的 web 開發(fā)包(spring-boot-starter-web)里面;

org.springframework.validation.annotation.Validated:只用 Spring Validator 校驗機制使用,是 Spring 做得一個自定義注解,增強了分組功能;

  • 標注位置

@Validated:可以用在類型、方法和方法參數(shù)上,不能用于成員屬性(field)上。如果注解在成員屬性上,則會報不適用于field的錯誤;? ? ? ? ? ? ? ? ??

@Valid:可以用在方法、構造函數(shù)、方法參數(shù)和成員屬性(field)上;

  • 分組支持

@Validated:提供分組功能,可以在參數(shù)驗證時,根據(jù)不同的分組采用不同的驗證機制;

@Valid:沒有分組的功能,不能進行分組校驗;

  • 嵌套支持

@Validated:不能進行嵌套對象校驗;

@Valid:可以進行嵌套校驗,但是,需要在嵌套的字段上面加上注解;

2. 常用的校驗方法

  • Debug進入jar包,可以看到全量的相關注解:

Java代碼瘦身,巧用 @Valid,@Validated 的分組校驗和嵌套檢驗,實現(xiàn)高階參數(shù)校驗操作

  • 簡述一些常用注解:
注解 使用方法
@AssertFalse 被校驗的對象必須為 true。
@AssertTrue 被校驗的對象必須為?false。
@DecimalMax(value = "val") 被校驗的對象必須是數(shù)字,而且小于等于 val。
@DecimalMin(value = "val") 被校驗的對象必須是數(shù)字,而且大于等于 val
@Digits(integer = in, fraction = fra) 校驗字符串是否是符合指定格式的數(shù)字:in 指定整數(shù)精度,fra 指定小數(shù)精度。
@Future 被校驗的對象(日期類型)必須是將來時間,即:比當前時間晚。
@Past :被校驗的對象(日期類型)必須是過去時間,即:比當前時間早。
@Size(min = min, max = max) 元素值的在 min 和 max(包含)指定區(qū)間之內(nèi),如字符長度、集合大?。▽τ诩蟻碚f,null 和空字符串都是算長度的)。

@NotBlank

所注解的元素不能為null且不能為空白,并且必須至少包含一個非空白字符,用于校驗CharSequence(含String、StringBuilder和StringBuffer)。只支持字符類型。


@NotEmpty
所注解的元素不能為null且長度大于0,可以是空白,用于校驗 CharSequence、數(shù)組、Collection 和 Map。

@NotNull
所注解的元素不能為 null,接受任何類型。

@Null
所注解的元素必須為 null,接受任何類型。
@Pattern(regexp = "正則表達式", message = "")

所注解的元素必須匹配指定的正則表達式。

注意:如果 @Pattern 所注解的元素是null,則@Pattern 注解會返回 true,即也會通過校驗,所以應該把 @Pattern 注解和 @NotNull 注解結(jié)合使用。

3. @Validated分組校驗

場景:多個 Restfull 接口共用一個標準 Bean,每個接口的參數(shù)相同,但是需要校驗的參數(shù)(必輸項)卻不完全相同,這樣的場景可以使用?@Validated,因為它提供了分組校驗的功能。

分組 說明

隱式分組

1.沒有顯式分組的默認都是 Default 組;

2.顯式分組之后,剩下的那些沒有被劃分到自建組的字段都屬于 Default 組;

3.平常我們寫?@Validated注解的時候,不寫分組的話默認就是?@Validated(group = {Default.class});

顯式分組

1.自定義interface接口的分組,屬于自建組;

2.自建組可以繼承 Default.class,也可以不繼承?Default.class,兩者意義不同;

3.多個分組可以一起實用;

4.分組機制讓我們可以很靈活的使用對象里面的某些字段,以實現(xiàn)高權限等級參數(shù)傳遞校驗等操作。

  • 新建請求對象

@Data
public class TeacherDTO {

    @NotBlank(message = "id必傳")
    private String id;

    @NotBlank(message = "不能沒有名稱")
    private String name;

    @NotNull(message = "age必傳")
    private Integer age;

    @NotBlank(message = "不能沒有idCard")
    private String idCard;

    @NotBlank(message = "老師不能沒有手機號", groups = OnlyTeacher.class)
    private String phone;

    @NotEmpty(message = "學生不能沒有書")
    @Size(min = 2, message = "學生必須有兩本書", groups = OnlyStudent.class)
    private List<String> bookNames;

    @NotEmpty
    @Size(min = 1, message = "老師不能沒有學生", groups = TeacherWithDefault.class)
    private List<String> studentList;
}
  • 新建分組

// Teacher分組
public interface TeacherValid { }

// Student分組
public interface StudentValid { }

// 繼承Default的分組
public interface OtherValid extends Default{ }
  • 接口測試

/**
 * Created by tjm on 2022/11/11.
 */
@RestController
@RequestMapping("/test")
public class TestValidController {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestValidController.class);

    /**
     * 測試 - 分組校驗 - 默認default
     */
    @PostMapping("/only/default")
    public Object testDefaultValid(@Validated TeacherDTO param, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.genFailResult(bindingResult.getFieldError().getDefaultMessage());
        }
        return ResultGenerator.genSuccessResult();
    }
    
    /**
     * 測試 - 分組校驗 - 只有teacher
     */
    @PostMapping("/only/teacher")
    public Object testOnlyTeacherValid(@Validated(OnlyTeacher.class) TeacherDTO param, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.genFailResult(bindingResult.getFieldError().getDefaultMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    /**
     * 測試 - 分組校驗 - 只有student
     */
    @PostMapping("/only/student")
    public Object testOnlyStudentValid(@Validated(OnlyStudent.class) TeacherDTO param, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.genFailResult(bindingResult.getFieldError().getDefaultMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    /**
     * 測試 - 分組校驗 - teacher + default
     */
    @PostMapping("/with/teacher")
    public Object testWithTeacherValid(@Validated({OnlyTeacher.class, Default.class}) TeacherDTO param, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.genFailResult(bindingResult.getFieldError().getDefaultMessage());
        }
        return ResultGenerator.genSuccessResult();
    }


    /**
     * 測試 - 分組校驗 - 繼承default
     */
    @PostMapping("/with/default")
    public Object testWithDefaultValid(@Validated(TeacherWithDefault.class) TeacherDTO param, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.genFailResult(bindingResult.getFieldError().getDefaultMessage());
        }
        return ResultGenerator.genSuccessResult();
    }
}
  • 結(jié)果

分組 校驗參數(shù)
只有 default id、name、age、idCard
只有 teacher phone
只有 student booknames
teacher + default id、name、age、idCard、phone
teacher 繼承 default id、name、age、idCard、studentList

4.@Valid嵌套校驗

  • 新建請求對象
public class Item {

    @NotNull(message = "id不能為空")
    @Min(value = 1, message = "id必須為正整數(shù)")
    private Long id;

    // 嵌套驗證必須用 @Valid
    @Valid             
    @NotNull(message = "props不能為空")
    @Size(min = 1, message = "props至少要有一個自定義屬性")
    private List<Prop> props;
}

public class Prop {

    @NotNull(message = "pid不能為空")
    @Min(value = 1, message = "pid必須為正整數(shù)")
    private Long pid;

    @NotNull(message = "vid不能為空")
    @Min(value = 1, message = "vid必須為正整數(shù)")
    private Long vid;

    @NotBlank(message = "pidName不能為空")
    private String pidName;

    @NotBlank(message = "vidName不能為空")
    private String vidName;
}
  • 接口測試
    /**
     * 測試 - 分組校驗 - 繼承default
     */
    @PostMapping("/item")
    public Object testItemValid(@Validated Item param, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.genFailResult(bindingResult.getFieldError().getDefaultMessage());
        }
        return ResultGenerator.genSuccessResult();
    }
  • 測試結(jié)果

1. 不僅校驗 Item 參數(shù),還會校驗子類 Prop 參數(shù);

2. 注意:嵌套驗證必須在子參數(shù)上用 @Valid。

5.Restfull層@Validated的使用

????????校驗參數(shù)的時候,如何判斷并返回失敗的結(jié)果?一般有兩種方式:

  • 全局異常捕獲
@ControllerAdvice
@RestController
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 非法參數(shù)驗證異常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(value = HttpStatus.OK)
    public ApiResult handleMethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        List<String> list = new ArrayList<>();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        for (FieldError fieldError : fieldErrors) {
            list.add(fieldError.getDefaultMessage());
        }
        Collections.sort(list);
        log.error("fieldErrors" + JSON.toJSONString(list));
        return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, list);
    }
}
  • 用 BindingResult 在實體類校驗信息返回結(jié)果綁定

????????即使是全局異常捕獲的方式,也能看到:校驗信息是被封裝在?BindingResult 對象里的,所以,我們也可以在 RestFull 層直接取。

1.?BindingResult用在實體類校驗信息返回結(jié)果綁定;

2.?BindingResult.hasErrors()判斷是否校驗通過,bindingResult.getFieldError().getDefaultMessage() 獲取在 TestEntity 的屬性設置的自定義message,如果沒有設置,則返回默認值 "javax.validation.constraints.XXX.message"。

? ? ? ? 可以看到,我上面的例子用的都是這種方法,我覺得這樣更方便、直觀,維護性更好。文章來源地址http://www.zghlxwxcb.cn/news/detail-443618.html


到了這里,關于Java代碼瘦身,巧用 @Valid,@Validated 的分組校驗和嵌套檢驗,實現(xiàn)高階參數(shù)校驗操作的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 如何優(yōu)雅的寫代碼-替代大量if else的@valid、@validated注解

    如何優(yōu)雅的寫代碼-替代大量if else的@valid、@validated注解

    @Valid 注解通常用于對象屬性字段的規(guī)則檢測,具體啥意思,下面讓我娓娓道來: 下面我們以新增一個員工為功能切入點,以常規(guī)寫法為背景,慢慢烘托出 @Valid 注解用法詳解。 那么,首先,我們會有一個員工對象 Employee,如下 :首先我們會有一個員工對象 Employee,如下 :

    2024年01月18日
    瀏覽(36)
  • Spring Boot @Validated 和Javax的@Valid配合使用

    Spring Boot @Validated 和Javax的@Valid配合使用

    @Validation 和@Valid 常常配合使用對傳輸?shù)膮?shù)進行數(shù)據(jù)校驗的注解,并通過配置全局異常處理器進行合理化的提示,增加用戶的體驗 并且@Validated可以通過分組來指定什么時候觸發(fā)什么樣的參數(shù)校驗(這里看一下就行,下面有說什么是分組) 其實不用這兩個注解也可以完成對傳

    2024年02月09日
    瀏覽(27)
  • Java參數(shù)校驗@Valid中@Length和@Size的用法和區(qū)別

    在Spring框架中,@Length和@Size都是用于參數(shù)長度校驗的注解,但它們之間存在一些關鍵的區(qū)別: @Length 是Hibernate Validator提供的一個注解,它用于校驗字符串的長度。 @Size 也是Hibernate Validator提供的注解,但它可以用于多種數(shù)據(jù)類型,不僅僅是字符串。對于字符串,它可以校驗長

    2024年04月15日
    瀏覽(26)
  • java如何優(yōu)雅的實現(xiàn)參數(shù)非空校驗,快速實現(xiàn)參數(shù)非空校驗,使用@valid實現(xiàn)參數(shù)非空校驗

    在java項目接口中,有些必傳參數(shù)需要進行非空校驗,如果參數(shù)過多,代碼會繁雜且冗余,如何優(yōu)雅的對參數(shù)進行非空校驗,下面是實現(xiàn)流程 用實體類接收參數(shù),使用非空注解編輯參數(shù)內(nèi)容 使用 @Valid 注解對參數(shù)進行攔截,整體進行非空校驗 如果是SpringBoot項目,引入web開發(fā)包

    2024年02月08日
    瀏覽(25)
  • spring-boot 請求參數(shù)校驗:注解 @Validated 的使用、手動校驗、自定義校驗

    spring-boot中可以用@validated來校驗數(shù)據(jù),如果數(shù)據(jù)異常則會統(tǒng)一拋出異常,方便異常中心統(tǒng)一處理。 spring-boot已經(jīng)引入了基礎包,所以直接使用就可以。 在屬性上添加校驗注解: 在Controller上添加 @Validated 注解 校驗未通過時,可能看到: 在 @Validated 后面緊跟著追加BindingResult,

    2023年04月16日
    瀏覽(33)
  • 【優(yōu)雅的參數(shù)驗證@Validated】@Validated參數(shù)校驗的使用及注解詳解——你還在用if做條件驗證?

    【優(yōu)雅的參數(shù)驗證@Validated】@Validated參數(shù)校驗的使用及注解詳解——你還在用if做條件驗證?

    請先看看下面代碼:(簡單舉個例子,代碼并不規(guī)范) 以上代碼主要是為了對用戶user實體進行條件驗證。 但是那么多的if, 寫得純純得小白一個,也使得代碼顯得臃腫不美觀不優(yōu)雅! 接下來,讓我們學習使用優(yōu)雅的參數(shù)驗證@Validated! @Valid和@Validated是Spring Validation框架提供

    2024年02月02日
    瀏覽(29)
  • Springboot——@valid 做字段校驗和自定義注解

    Springboot——@valid 做字段校驗和自定義注解

    再項目開發(fā)中,針對前端傳遞的參數(shù)信息,有些接口中需要寫大量的 if 判斷,導致代碼臃腫,不夠優(yōu)雅。 此時,可以使用 @Valid 實現(xiàn)基本的字段校驗。 springboot 2.3之前 ,直接進行開發(fā)即可,無需引用額外的依賴 集成在 spring-boot-starter-web 中。 springboot 2.3之后 需要額外引入

    2023年04月26日
    瀏覽(22)
  • CSS基礎學習--12 分組 和 嵌套 選擇器

    CSS基礎學習--12 分組 和 嵌套 選擇器

    一、分組選擇器 ????????在樣式表中有很多具有相同樣式的元素 ????????為了盡量減少代碼,你可以使用分組選擇器。 ???????? 每個選擇器用逗號分隔 。 ????????在下面的例子中,我們對以上代碼使用分組選擇器: 備注 :h1、h2與p標簽字體顏色都是綠色,?為

    2024年02月09日
    瀏覽(27)
  • Golang校驗字符串是否JSON格式方法json.Valid源碼解析

    上篇文章《Golang中如何校驗字符串是否為JSON格式?》主要講解了使用json.Valid校驗字符串是否JSON格式的使用方法,本文來剖析一下json.Valid方法的源碼。 json.Valid方法定義: scan := newScanner() 獲取一個 scanner 類型的對象,關鍵的是checkValid方法,checkValid源碼如下: 首先調(diào)用了sc

    2023年04月26日
    瀏覽(19)
  • element ui form表單循環(huán)嵌套 及嵌套表單item的校驗方法

    element ui form表單循環(huán)嵌套 及嵌套表單item的校驗方法

    html:? js:? 詳細的大家可以參考:element ui form循環(huán)嵌套表單 及嵌套表單的驗證方法(校驗)_element循環(huán)表單_RxnNing的博客-CSDN博客

    2024年02月09日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包