一文帶你揭秘SpringMvc參數值映射

前言

我們平時開發的接口參數類型,有簡單類型例如Long,String,也有JSON格式的,還有自定義對象類型。想一想,如果讓我們自己開發一套參數值映射代碼,還是挺復雜,一是需要處理的參數類型比較多,還有就是會有一些復雜的場景,比如對象的多層嵌套。今天我將從處理過程的抽象,常見傳參類型兩個大的方面講解參數值映射。

一.處理過程的抽象

說到參數映射處理的抽象,就不得不提到

HandlerMethodArgumentResolver接口:

接口有兩個方法: 1.boolean supportsParameter(MethodParameter parameter); 用來判斷實現類是否可以處理該類型的參數

2.Object resolveArgument(…) 經過讀取參數值,類型轉換,值映射等處理,返回參數 所有參數值處理類都需要實現此接口,遵從瞭設計模式中的模版模式。 處理過程通俗地說就是:從一堆螺絲刀裡面,挨個判斷,這把螺絲刀是否可以擰這個螺絲,如果型號剛好匹配,那就拿著這個螺絲刀去擰螺絲。 SpringMvc還給這些個螺絲刀,找瞭個工具箱,來存放他們。這個工具箱名字叫做: HandlerMethodArgumentResolverComposite,composite是混合,合成的意思。 HandlerMethodArgumentResolverComposite將所有的參數值處理類整合在一起。

二.常見傳參類型

1.自定義對象類型

示例:

@RequestMapping("/test1")
public String methodForObjectParam (FamilyDTO familyDTO){
    System.out.println("familyDTO:"+JSON.toJSONString(familyDTO));
    return "";
}

對應的參數值處理類為

ServletModelAttributeMethodProcessor

參數值映射的過程如下:

2.@RequestParam註解參數

示例:

@RequestMapping("/test3")
public String methodForRequestParam (@RequestParam Integer param){
    System.out.println("RequestParam:"+JSON.toJSONString(param));
    return "";
}

對應的參數值處理類為RequestParamMethodArgumentResolver

參數映射的步驟如下:

1.1從request中獲取參數名對應的值

1.2參數值類型轉換,從request中獲取的參數值為String,需要轉化為對應Integer等類型。 spring-core提供瞭超級多的類型轉換工具,我截取瞭部分類:

Spring的強大不僅僅在它的設計思想,對各種復雜情況的支持,還有強大的代碼底層。

3.@RequestBody註解參數

示例:

@RequestMapping("/test6")
public String methodForRequestBody (@RequestBody FamilyDTO familyDTO){
    System.out.println("methodForNormalParam:"+JSON.toJSONString(familyDTO));
    return "";
}

對應的參數值處理類為:RequestResponseBodyMethodProcessor

參數映射的步驟如下:

1.1將body反序列化為對象

1.2如果類型為Optional,創建Optional類型對象

4.簡單類型,無@RequestParam註解

示例:

@RequestMapping("/test5")
public String methodForNormalParam (Integer param){
    System.out.println("methodForNormalParam:"+JSON.toJSONString(param));
    return "";
}

對於參數param,和帶有@RequestParam註解的參數一樣,使用 RequestParamMethodArgumentResolver類進行參數值映射。

SpringMvc接口調用的核心方法invokeForRequest在InvocableHandlerMethod類中,大傢有興趣,可以自己閱讀下源碼:

public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
      Object... providedArgs) throws Exception {
   //從request中讀取,轉化參數值
   Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
   if (logger.isTraceEnabled()) {
      logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
            "' with arguments " + Arrays.toString(args));
   }
   //方法的調用
   Object returnValue = doInvoke(args);
   if (logger.isTraceEnabled()) {
      logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
            "] returned [" + returnValue + "]");
   }
   return returnValue;
}

總結

到此這篇關於SpringMvc參數值映射的文章就介紹到這瞭,更多相關SpringMvc參數值映射內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: