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

Java Validation Api實(shí)現(xiàn)原理解析

 更新時(shí)間:2020年09月07日 11:08:01   作者:果果蟲  
這篇文章主要介紹了Java Validation Api實(shí)現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

前言:

  涉及知識(shí)點(diǎn):AOP、攔截器相關(guān)

  功能主要實(shí)現(xiàn)類:因?yàn)閎ean validation只提供了接口并未實(shí)現(xiàn),使用時(shí)需要加上一個(gè)provider的包,例如hibernate-validator

  范圍: 注解:@Valid @RequestBudy

  主要實(shí)現(xiàn)類:RequestResponseBodyMethodProcessor

  處理器:HandlerMethodArgumentResolver

  注解說明:

  • @Valid:標(biāo)準(zhǔn)JSR-303規(guī)范的標(biāo)記型注解,用來標(biāo)記驗(yàn)證屬性和方法返回值,進(jìn)行級(jí)聯(lián)和遞歸校驗(yàn),@Valid可用于方法、字段、構(gòu)造器和參數(shù)上
  • @RequestBudy 請(qǐng)求的Body體,只能被讀取一次

RequestResponseBodyMethodProcessor 類說明:

// @since 3.1
public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {

  @Override
  public boolean supportsParameter(MethodParameter parameter) {
    return parameter.hasParameterAnnotation(RequestBody.class);
  }
  // 類上或者方法上標(biāo)注了@ResponseBody注解都行
  @Override
  public boolean supportsReturnType(MethodParameter returnType) {
    return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class));
  }

  // 這是處理入?yún)⒎庋b校驗(yàn)的入口,也是本文關(guān)注的焦點(diǎn)
  @Override
  public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
      NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {

    // 它是支持`Optional`容器的
    parameter = parameter.nestedIfOptional();
    // 使用消息轉(zhuǎn)換器HttpInputMessage把request請(qǐng)求轉(zhuǎn)換出來,拿到值~~~
    // 此處注意:比如本例入?yún)⑹荘erson類,所以經(jīng)過這里處理會(huì)生成一個(gè)空的Person對(duì)象出來(反射)
    Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());

    // 獲取到入?yún)⒌拿Q,其實(shí)不叫形參名字,應(yīng)該叫objectName給校驗(yàn)時(shí)用的
    // 請(qǐng)注意:這里的名稱是類名首字母小寫,并不是你方法里寫的名字。比如本利若形參名寫為personAAA,但是name的值還是person
    // 但是注意:`parameter.getParameterName()`的值可是personAAA
    String name = Conventions.getVariableNameForParameter(parameter);

    // 只有存在binderFactory才會(huì)去完成自動(dòng)的綁定、校驗(yàn)~
    // 此處web環(huán)境為:ServletRequestDataBinderFactory
    if (binderFactory != null) {
      WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);

      // 顯然傳了參數(shù)才需要去綁定校驗(yàn)嘛
      if (arg != null) {

        // 這里完成數(shù)據(jù)綁定+數(shù)據(jù)校驗(yàn)~~~~~(綁定的錯(cuò)誤和校驗(yàn)的錯(cuò)誤都會(huì)放進(jìn)Errors里)
        // Applicable:適合
        validateIfApplicable(binder, parameter);

        // 若有錯(cuò)誤消息hasErrors(),并且僅跟著的一個(gè)參數(shù)不是Errors類型,Spring MVC會(huì)主動(dòng)給你拋出MethodArgumentNotValidException異常
        // 否則,調(diào)用者自行處理
        if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
          throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
        }
      }

      // 把錯(cuò)誤消息放進(jìn)去 證明已經(jīng)校驗(yàn)出錯(cuò)誤了~~~
      // 后續(xù)邏輯會(huì)判斷MODEL_KEY_PREFIX這個(gè)key的~~~~
      if (mavContainer != null) {
        mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
      }
    }

    return adaptArgumentIfNecessary(arg, parameter);
  }

  // 校驗(yàn),如果合適的話。使用WebDataBinder,失敗信息最終也都是放在它身上~ 本方法是本文關(guān)注的焦點(diǎn)
  // 入?yún)ⅲ篗ethodParameter parameter
  protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
    // 拿到標(biāo)注在此參數(shù)上的所有注解們(比如此處有@Valid和@RequestBody兩個(gè)注解)
    Annotation[] annotations = parameter.getParameterAnnotations();
    for (Annotation ann : annotations) {
      // 先看看有木有@Validated
      Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);

      // 這個(gè)里的判斷是關(guān)鍵:可以看到標(biāo)注了@Validated注解 或者注解名是以Valid打頭的 都會(huì)有效哦
      //注意:這里可沒說必須是@Valid注解。實(shí)際上你自定義注解,名稱只要一Valid開頭都成~~~~~
      if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
        // 拿到分組group后,調(diào)用binder的validate()進(jìn)行校驗(yàn)~~~~
        // 可以看到:拿到一個(gè)合適的注解后,立馬就break了~~~
        // 所以若你兩個(gè)主機(jī)都標(biāo)注@Validated和@Valid,效果是一樣滴~
        Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
        Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
        binder.validate(validationHints);
        break;
      }
    }
  }
  ...
}

  可以看得,這個(gè)類應(yīng)該是陌生的,它能夠處理@ResponseBody注解返回值;它還有另一個(gè)能力是:它能夠處理請(qǐng)求參數(shù)(當(dāng)然也是標(biāo)注了@RequestBody的JavaBean)
所以它既是個(gè)處理返回值的HandlerMethodReturnValueHandler,又是一個(gè)處理入?yún)⒌腍andlerMethodArgumentResolver。所以它命名為Processor而不是Resolver/Handler。

  這是使用@RequestBody結(jié)合@Valid完成數(shù)據(jù)校驗(yàn)的基本原理。其實(shí)當(dāng)Spring MVC在處理@RequestPart注解入?yún)?shù)據(jù)時(shí),也會(huì)執(zhí)行綁定、校驗(yàn)的相關(guān)邏輯。對(duì)應(yīng)處理器是RequestPartMethodArgumentResolver,原理大體上和這相似,它主要處理Multipart相關(guān),本文忽略~

以上就是dui'y對(duì)于@Valid標(biāo)注的@RequestBody的JavaBean的原理說明,敬請(qǐng)指點(diǎn)。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決maven打包失敗:程序包xxxx不存在問題

    解決maven打包失敗:程序包xxxx不存在問題

    這篇文章主要介紹了解決maven打包失敗:程序包xxxx不存在問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Sentinel熱門詞匯限流的實(shí)現(xiàn)詳解

    Sentinel熱門詞匯限流的實(shí)現(xiàn)詳解

    這篇文章主要介紹了使用Sentinel對(duì)熱門詞匯進(jìn)行限流的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • java 商戶PC端接入支付寶支付的實(shí)現(xiàn)方法

    java 商戶PC端接入支付寶支付的實(shí)現(xiàn)方法

    這篇文章主要介紹了java 商戶PC端接入支付寶支付的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java中ReentrantLock和ReentrantReadWriteLock的原理

    Java中ReentrantLock和ReentrantReadWriteLock的原理

    這篇文章主要介紹了Java中ReentrantLock和ReentrantReadWriteLock的原理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-09-09
  • Java應(yīng)用自動(dòng)擴(kuò)縮容的三種實(shí)現(xiàn)方案

    Java應(yīng)用自動(dòng)擴(kuò)縮容的三種實(shí)現(xiàn)方案

    你是否曾經(jīng)為如何應(yīng)對(duì)突如其來的流量高峰而頭疼不已?或者在面對(duì)資源浪費(fèi)時(shí)感到無奈?別擔(dān)心!本文將帶你深入探索Java應(yīng)用的三大自動(dòng)擴(kuò)縮容策略無論你是編程新手還是經(jīng)驗(yàn)豐富的開發(fā)者,這篇文章都將為你提供詳盡的指導(dǎo),幫助你在自動(dòng)擴(kuò)縮容領(lǐng)域一展身手
    2025-06-06
  • spring-boot整合dubbo:Spring-boot-dubbo-starter

    spring-boot整合dubbo:Spring-boot-dubbo-starter

    這篇文章主要介紹了spring-boot整合dubbo:Spring-boot-dubbo-starter的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-05-05
  • 關(guān)于java命令的本質(zhì)邏輯揭秘過程

    關(guān)于java命令的本質(zhì)邏輯揭秘過程

    Java是通過java虛擬機(jī)來裝載和執(zhí)行編譯文件(class文件)的,java虛擬機(jī)通過命令java  option 來啟動(dòng),這篇文章主要給大家介紹了關(guān)于java命令的本質(zhì)邏輯揭秘的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-05-05
  • SpringBoot之controller參數(shù)校驗(yàn)詳解

    SpringBoot之controller參數(shù)校驗(yàn)詳解

    介紹了Java中使用@Validated和@Valid進(jìn)行參數(shù)校驗(yàn)的方法,包括不同標(biāo)簽的使用場景、基本屬性和一些常用的注解類型,同時(shí),還討論了如何在控制器中使用這些校驗(yàn)標(biāo)簽,以及如何處理校驗(yàn)結(jié)果和自定義錯(cuò)誤消息,最后,還介紹了如何實(shí)現(xiàn)分組校驗(yàn)和嵌套校驗(yàn),并提供了一些示例代碼
    2024-11-11
  • Java中ArrayList具體實(shí)現(xiàn)之簡單的洗牌算法

    Java中ArrayList具體實(shí)現(xiàn)之簡單的洗牌算法

    這篇文章主要給大家介紹了Java中ArrayList具體實(shí)現(xiàn)之簡單的洗牌算法,文中通過代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-12-12
  • Java中用Socket實(shí)現(xiàn)HTTP文件上傳實(shí)例

    Java中用Socket實(shí)現(xiàn)HTTP文件上傳實(shí)例

    本篇文章主要介紹了Java中用Socket實(shí)現(xiàn)HTTP文件上傳實(shí)例,詳細(xì)的介紹了通過讀取Socket的輸入流來實(shí)現(xiàn)一個(gè)文件上傳的功能,有興趣的同學(xué)可以一起了解一下
    2017-04-04

最新評(píng)論

体育| 三亚市| 左权县| 丹巴县| 应用必备| 吴江市| 来安县| 南澳县| 山丹县| 永兴县| 南京市| 多伦县| 延长县| 微山县| 尤溪县| 汝州市| 平陆县| 封开县| 延津县| 敦化市| 甘谷县| 周宁县| 会宁县| 宁国市| 黎平县| 霍州市| 湖南省| 芦溪县| 电白县| 肃北| 珠海市| 曲麻莱县| 靖安县| 宜州市| 岢岚县| 乐安县| 上思县| 易门县| 观塘区| 嘉义市| 正蓝旗|