一文帶你揭秘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!
推薦閱讀:
- SpringMvc接受請求參數的幾種情況演示
- 聊聊@RequestParam,@PathParam,@PathVariable等註解的區別
- SpringBoot多種場景傳參模式
- SpringMVC 接收前端傳遞的參數四種方式小結
- 基於controller使用map接收參數的註意事項