亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring常見(jiàn)錯(cuò)誤之Web嵌套對(duì)象校驗(yàn)失效解決辦法

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

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

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

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 對(duì)象做了合法性要求(@Size(max = 10)),當(dāng)我們使用下面的請(qǐng)求(請(qǐng)求 body 攜帶一個(gè)聯(lián)系電話信息超過(guò) 10 位),測(cè)試校驗(yàn)會(huì)發(fā)現(xiàn)這個(gè)約束并不生效。

定義完對(duì)象后,我們?cè)俣x一個(gè) 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ù)代碼
    };
}

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

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

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

案例解析

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

在校驗(yàn)執(zhí)行時(shí),首先會(huì)根據(jù) Student 的類型定義找出所有的校驗(yàn)點(diǎn),然后對(duì) Student 對(duì)象實(shí)例執(zhí)行校驗(yàn),這個(gè)邏輯過(guò)程可以參考代碼 ValidatorImpl#validate:

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

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

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

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

在組裝 BeanMetaData 過(guò)程中,會(huì)根據(jù)成員字段是否標(biāo)記了 @Valid 來(lái)決定(記錄)這個(gè)字段以后是否做級(jí)聯(lián)校驗(yà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ù)做具體校驗(yàn)時(shí),做級(jí)聯(lián)校驗(yàn),而級(jí)聯(lián)校驗(yàn)的過(guò)程與宿主對(duì)象(即 Student)的校驗(yàn)過(guò)程大體相同,即先根據(jù)對(duì)象類型獲取定義再來(lái)做校驗(yàn)。

在當(dāng)前案例代碼中,phone 字段并沒(méi)有被 @Valid 標(biāo)記,所以關(guān)于這個(gè)字段信息的 cascading 屬性肯定是 false,因此在校驗(yàn) Student 時(shí)并不會(huì)級(jí)聯(lián)校驗(yàn)它。

問(wèn)題修正

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

@Valid
private Phone phone;

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

總結(jié)  

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

相關(guān)文章

  • JNDI在JavaEE中的角色_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    JNDI在JavaEE中的角色_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了JNDI在JavaEE中的角色,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 詳解Spring加載Properties配置文件的四種方式

    詳解Spring加載Properties配置文件的四種方式

    這篇文章主要介紹了詳解Spring加載Properties配置文件的四種方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 兩個(gè)List集合取相同重復(fù)數(shù)據(jù)的方法

    兩個(gè)List集合取相同重復(fù)數(shù)據(jù)的方法

    今天小編就為大家分享一篇關(guān)于兩個(gè)List集合取相同重復(fù)數(shù)據(jù)的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • Java連接mysql數(shù)據(jù)庫(kù)以及mysql驅(qū)動(dòng)jar包下載和使用方法

    Java連接mysql數(shù)據(jù)庫(kù)以及mysql驅(qū)動(dòng)jar包下載和使用方法

    這篇文章主要給大家介紹了關(guān)于Java連接mysql數(shù)據(jù)庫(kù)以及mysql驅(qū)動(dòng)jar包下載和使用方法,MySQL是一款常用的關(guān)系型數(shù)據(jù)庫(kù),它的JDBC驅(qū)動(dòng)程序使得我們可以通過(guò)Java程序連接MySQL數(shù)據(jù)庫(kù)進(jìn)行數(shù)據(jù)操作,需要的朋友可以參考下
    2023-11-11
  • Maven的配置文件pom.xml詳解(含常用plugin)

    Maven的配置文件pom.xml詳解(含常用plugin)

    pom.xml是Maven項(xiàng)目的核心配置文件,它是 項(xiàng)目對(duì)象模型 - Project Object Model(POM)的縮寫,本文我們將全面解析pom.xml,了解其結(jié)構(gòu)和屬性,以及如何使用它來(lái)管理項(xiàng)目,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • 你應(yīng)該知道的21個(gè)Java核心技術(shù)

    你應(yīng)該知道的21個(gè)Java核心技術(shù)

    Java的21個(gè)核心技術(shù)點(diǎn),你知道嗎?這篇文章主要為大家詳細(xì)介紹了Java核心技術(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • JAVA設(shè)計(jì)模式中的策略模式你了解嗎

    JAVA設(shè)計(jì)模式中的策略模式你了解嗎

    這篇文章主要為大家詳細(xì)介紹了JAVA設(shè)計(jì)模式中的策略模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • 基于MyBatis的簡(jiǎn)單使用(推薦)

    基于MyBatis的簡(jiǎn)單使用(推薦)

    下面小編就為大家?guī)?lái)一篇基于MyBatis的簡(jiǎn)單使用(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Java實(shí)現(xiàn)二維碼QRCode的編碼和解碼與示例解析

    Java實(shí)現(xiàn)二維碼QRCode的編碼和解碼與示例解析

    本文主要介紹Java實(shí)現(xiàn)二維碼QRCode的編碼和解碼,這里給大家一個(gè)小示例以便理解,有需要的小伙伴可以參考下
    2016-08-08
  • 基于Java接口回調(diào)詳解

    基于Java接口回調(diào)詳解

    這篇文章主要介紹了Java接口回調(diào)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評(píng)論