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

Java Validation Api實現原理解析

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

前言:

  涉及知識點:AOP、攔截器相關

  功能主要實現類:因為bean validation只提供了接口并未實現,使用時需要加上一個provider的包,例如hibernate-validator

  范圍: 注解:@Valid @RequestBudy

  主要實現類:RequestResponseBodyMethodProcessor

  處理器:HandlerMethodArgumentResolver

  注解說明:

  • @Valid:標準JSR-303規(guī)范的標記型注解,用來標記驗證屬性和方法返回值,進行級聯(lián)和遞歸校驗,@Valid可用于方法、字段、構造器和參數上
  • @RequestBudy 請求的Body體,只能被讀取一次

RequestResponseBodyMethodProcessor 類說明:

// @since 3.1
public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {

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

  // 這是處理入參封裝校驗的入口,也是本文關注的焦點
  @Override
  public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
      NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {

    // 它是支持`Optional`容器的
    parameter = parameter.nestedIfOptional();
    // 使用消息轉換器HttpInputMessage把request請求轉換出來,拿到值~~~
    // 此處注意:比如本例入參是Person類,所以經過這里處理會生成一個空的Person對象出來(反射)
    Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());

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

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

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

        // 這里完成數據綁定+數據校驗~~~~~(綁定的錯誤和校驗的錯誤都會放進Errors里)
        // Applicable:適合
        validateIfApplicable(binder, parameter);

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

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

    return adaptArgumentIfNecessary(arg, parameter);
  }

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

      // 這個里的判斷是關鍵:可以看到標注了@Validated注解 或者注解名是以Valid打頭的 都會有效哦
      //注意:這里可沒說必須是@Valid注解。實際上你自定義注解,名稱只要一Valid開頭都成~~~~~
      if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
        // 拿到分組group后,調用binder的validate()進行校驗~~~~
        // 可以看到:拿到一個合適的注解后,立馬就break了~~~
        // 所以若你兩個主機都標注@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;
      }
    }
  }
  ...
}

  可以看得,這個類應該是陌生的,它能夠處理@ResponseBody注解返回值;它還有另一個能力是:它能夠處理請求參數(當然也是標注了@RequestBody的JavaBean)
所以它既是個處理返回值的HandlerMethodReturnValueHandler,又是一個處理入參的HandlerMethodArgumentResolver。所以它命名為Processor而不是Resolver/Handler。

  這是使用@RequestBody結合@Valid完成數據校驗的基本原理。其實當Spring MVC在處理@RequestPart注解入參數據時,也會執(zhí)行綁定、校驗的相關邏輯。對應處理器是RequestPartMethodArgumentResolver,原理大體上和這相似,它主要處理Multipart相關,本文忽略~

以上就是dui'y對于@Valid標注的@RequestBody的JavaBean的原理說明,敬請指點。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

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

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

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

    Sentinel熱門詞匯限流的實現詳解

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

    java 商戶PC端接入支付寶支付的實現方法

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

    Java中ReentrantLock和ReentrantReadWriteLock的原理

    這篇文章主要介紹了Java中ReentrantLock和ReentrantReadWriteLock的原理,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-09-09
  • Java應用自動擴縮容的三種實現方案

    Java應用自動擴縮容的三種實現方案

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

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

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

    關于java命令的本質邏輯揭秘過程

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

    SpringBoot之controller參數校驗詳解

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

    Java中ArrayList具體實現之簡單的洗牌算法

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

    Java中用Socket實現HTTP文件上傳實例

    本篇文章主要介紹了Java中用Socket實現HTTP文件上傳實例,詳細的介紹了通過讀取Socket的輸入流來實現一個文件上傳的功能,有興趣的同學可以一起了解一下
    2017-04-04

最新評論

贵港市| 东山县| 哈密市| 阿拉善右旗| 方山县| 高台县| 霍城县| 洛隆县| 阳泉市| 抚顺县| 垦利县| 德格县| 舞钢市| 吴桥县| 滁州市| 台山市| 和顺县| 大同市| 南宫市| 常熟市| 益阳市| 九江市| 金平| 五指山市| 日土县| 宜良县| 河南省| 祁连县| 凤山市| 福州市| 通渭县| 阿克苏市| 永顺县| 抚州市| 富宁县| 库伦旗| 三河市| 和龙市| 宁河县| 贞丰县| 吐鲁番市|