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

Spring常見錯誤之Web嵌套對象校驗失效解決辦法

 更新時間:2025年01月21日 08:33:07   作者:造夢師阿鵬  
這篇文章主要介紹了Spring常見錯誤之Web嵌套對象校驗失效解決的相關(guān)資料,通過在Phone對象上添加@Valid注解,問題得以解決,需要的朋友可以參考下

問題復(fù)現(xiàn)

當開發(fā)一個學(xué)籍管理系統(tǒng)時,我們會提供了一個 API 接口去添加學(xué)生的相關(guān)信息,學(xué)生中有個嵌套屬性聯(lián)系電話,其對象定義參考下面的代碼:

import lombok.Data;
import javax.validation.constraints.Size;
@Data
public class Student {
    @Size(max = 10)
    private String name;
    private short age;
    private Phone phone;
}

@Data
class Phone {
    @Size(max = 10)
    private String number;
}

這里我們也給 Phone 對象做了合法性要求(@Size(max = 10)),當我們使用下面的請求(請求 body 攜帶一個聯(lián)系電話信息超過 10 位),測試校驗會發(fā)現(xiàn)這個約束并不生效。

定義完對象后,我們再定義一個 Controller 去使用它,使用方法如下:

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
@Validated
public class StudentController {
    @RequestMapping(path = "students", method = RequestMethod.POST)
    public void addStudent(@Validated @RequestBody Student student){
        log.info("add new student: {}", student.toString());
        //省略業(yè)務(wù)代碼
    };
}

我們提供了一個支持學(xué)生信息添加的接口。啟動服務(wù)后,使用 IDEA 自帶的 HTTP Client 工具來發(fā)送下面的請求以添加一個學(xué)生:

POST http://localhost:8080/students
Content-Type: application/json
{
  "name": "xiaoming",
  "age": 10,
  "phone": {"number":"12306123061230612306"}
}

發(fā)現(xiàn)校驗器并沒有生效。

案例解析

關(guān)于 student 本身的 Phone 類型成員是否校驗是在校驗過程中(即案例 1 中的代碼行 binder.validate(validationHints))決定的。

在校驗執(zhí)行時,首先會根據(jù) Student 的類型定義找出所有的校驗點,然后對 Student 對象實例執(zhí)行校驗,這個邏輯過程可以參考代碼 ValidatorImpl#validate:

@Override
public final <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {
   //省略部分非關(guān)鍵代碼
   Class<T> rootBeanClass = (Class<T>) object.getClass();
   //獲取校驗對象類型的“信息”(包含“約束”)
   BeanMetaData<T> rootBeanMetaData = beanMetaDataManager.getBeanMetaData( rootBeanClass );

   if ( !rootBeanMetaData.hasConstraints() ) {
      return Collections.emptySet();
   }

   //省略部分非關(guān)鍵代碼
   //執(zhí)行校驗
   return validateInContext( validationContext, valueContext, validationOrder );
}

這里語句"beanMetaDataManager.getBeanMetaData( rootBeanClass )"根據(jù) Student 類型組裝出 BeanMetaData,BeanMetaData 即包含了需要做的校驗(即 Constraint)。

在組裝 BeanMetaData 過程中,會根據(jù)成員字段是否標記了 @Valid 來決定(記錄)這個字段以后是否做級聯(lián)校驗,參考代碼 AnnotationMetaDataProvider#getCascadingMetaData:

private CascadingMetaDataBuilder getCascadingMetaData(Type type, AnnotatedElement annotatedElement,
      Map<TypeVariable<?>, CascadingMetaDataBuilder> containerElementTypesCascadingMetaData) {
   return CascadingMetaDataBuilder.annotatedObject( type, annotatedElement.isAnnotationPresent( Valid.class ), containerElementTypesCascadingMetaData,
               getGroupConversions( annotatedElement ) );
}

在上述代碼中"annotatedElement.isAnnotationPresent( Valid.class )"決定了 CascadingMetaDataBuilder#cascading 是否為 true。如果是,則在后續(xù)做具體校驗時,做級聯(lián)校驗,而級聯(lián)校驗的過程與宿主對象(即 Student)的校驗過程大體相同,即先根據(jù)對象類型獲取定義再來做校驗。

在當前案例代碼中,phone 字段并沒有被 @Valid 標記,所以關(guān)于這個字段信息的 cascading 屬性肯定是 false,因此在校驗 Student 時并不會級聯(lián)校驗它。

問題修正

從源碼級別了解了嵌套 Validation 失敗的原因后,我們會發(fā)現(xiàn),要讓嵌套校驗生效,解決的方法只有一種,就是加上 @Valid,修正代碼如下:

@Valid
private Phone phone;

當修正完問題后,我們會發(fā)現(xiàn)校驗生效了。而如果此時去調(diào)試修正后的案例代碼,會看到 phone 字段 MetaData 信息中的 cascading 確實為 true 了,參考下圖:

總結(jié)  

到此這篇關(guān)于Spring常見錯誤之Web嵌套對象校驗失效解決辦法的文章就介紹到這了,更多相關(guān)Spring Web嵌套對象校驗失效內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • maven環(huán)境變量配置以及失敗原因解析

    maven環(huán)境變量配置以及失敗原因解析

    這篇文章主要為大家詳細介紹了maven環(huán)境變量配置教程,以及為大家解析了安裝失敗的原因,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • java中基本注解的知識點總結(jié)

    java中基本注解的知識點總結(jié)

    在本篇文章里小編給大家整理的是一篇關(guān)于java中基本注解的知識點總結(jié),有需要的朋友們可以跟著學(xué)習(xí)下。
    2021-06-06
  • Spring Boot整合mybatis并自動生成mapper和實體實例解析

    Spring Boot整合mybatis并自動生成mapper和實體實例解析

    本文是小編給大家總結(jié)的關(guān)于Spring Boot整合mybatis并自動生成mapper和實體的內(nèi)容,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-05-05
  • Java通過自定義類加載器實現(xiàn)類隔離

    Java通過自定義類加載器實現(xiàn)類隔離

    類隔離是一種通過類加載器實現(xiàn)加載所需類的實現(xiàn)方式,使得不同版本類間隔離,避免了使用沖突問題。本文將通過自定義的類加載器實現(xiàn)類隔離,感興趣的可以了解一下
    2022-08-08
  • Springboot?注解EqualsAndHashCode詳解

    Springboot?注解EqualsAndHashCode詳解

    注解@EqualsAndHashCode主要用于自動生成equals方法和hashCode方法,callSuper屬性為true時,生成的方法會包括父類字段,為false則只包含當前類字段,IDEA工具中有檢查提示并可自動修復(fù)相關(guān)代碼,確保注解正確使用,更多詳解可查閱相關(guān)文檔
    2024-10-10
  • Java垃圾回收機制的finalize方法實例分析

    Java垃圾回收機制的finalize方法實例分析

    這篇文章主要介紹了Java垃圾回收機制的finalize方法,結(jié)合實例形式分析了finalize方法的特點及在垃圾回收機制中的相關(guān)操作技巧,需要的朋友可以參考下
    2019-08-08
  • Java Web實現(xiàn)自動登陸功能

    Java Web實現(xiàn)自動登陸功能

    這篇文章主要為大家詳細介紹了Java Web實現(xiàn)自動登陸功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • java利用mybatis攔截器統(tǒng)計sql執(zhí)行時間示例

    java利用mybatis攔截器統(tǒng)計sql執(zhí)行時間示例

    這篇文章主要介紹了java利用mybatis攔截器統(tǒng)計sql執(zhí)行時間示例,該攔截器攔截mybatis的query和update操作,能統(tǒng)計sql執(zhí)行時間
    2014-03-03
  • 徹底解決Spring MVC中文亂碼問題的方案

    徹底解決Spring MVC中文亂碼問題的方案

    這篇文章主要介紹了徹底解決Spring MVC中文亂碼問題的方案,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2016-11-11
  • Spring之@Qualifier注解的具體使用

    Spring之@Qualifier注解的具體使用

    本文主要介紹了Spring之@Qualifier注解的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08

最新評論

威远县| 南丹县| 科尔| 兴安盟| 安阳市| 古蔺县| 崇礼县| 黑河市| 青岛市| 东辽县| 台中县| 五原县| 东乌珠穆沁旗| 新津县| 峨眉山市| 宁明县| 吉安县| 牙克石市| 阳泉市| 金川县| 望城县| 绥芬河市| 徐闻县| 高邮市| 噶尔县| 蛟河市| 永平县| 砀山县| 大英县| 元氏县| 孟津县| 苍南县| 平远县| 昌江| 高密市| 东乡族自治县| 正阳县| 玉树县| 新闻| 逊克县| 铜鼓县|