一文帶你揭秘SpringMvc參數(shù)值映射
前言
我們平時(shí)開發(fā)的接口參數(shù)類型,有簡(jiǎn)單類型例如Long,String,也有JSON格式的,還有自定義對(duì)象類型。想一想,如果讓我們自己開發(fā)一套參數(shù)值映射代碼,還是挺復(fù)雜,一是需要處理的參數(shù)類型比較多,還有就是會(huì)有一些復(fù)雜的場(chǎng)景,比如對(duì)象的多層嵌套。今天我將從處理過(guò)程的抽象,常見傳參類型兩個(gè)大的方面講解參數(shù)值映射。
一.處理過(guò)程的抽象
說(shuō)到參數(shù)映射處理的抽象,就不得不提到
HandlerMethodArgumentResolver接口:
接口有兩個(gè)方法: 1.boolean supportsParameter(MethodParameter parameter); 用來(lái)判斷實(shí)現(xiàn)類是否可以處理該類型的參數(shù)
2.Object resolveArgument(...) 經(jīng)過(guò)讀取參數(shù)值,類型轉(zhuǎn)換,值映射等處理,返回參數(shù) 所有參數(shù)值處理類都需要實(shí)現(xiàn)此接口,遵從了設(shè)計(jì)模式中的模版模式。 處理過(guò)程通俗地說(shuō)就是:從一堆螺絲刀里面,挨個(gè)判斷,這把螺絲刀是否可以擰這個(gè)螺絲,如果型號(hào)剛好匹配,那就拿著這個(gè)螺絲刀去擰螺絲。 SpringMvc還給這些個(gè)螺絲刀,找了個(gè)工具箱,來(lái)存放他們。這個(gè)工具箱名字叫做: HandlerMethodArgumentResolverComposite,composite是混合,合成的意思。 HandlerMethodArgumentResolverComposite將所有的參數(shù)值處理類整合在一起。
二.常見傳參類型
1.自定義對(duì)象類型
示例:
@RequestMapping("/test1") public String methodForObjectParam (FamilyDTO familyDTO){ System.out.println("familyDTO:"+JSON.toJSONString(familyDTO)); return ""; }
對(duì)應(yīng)的參數(shù)值處理類為
ServletModelAttributeMethodProcessor
參數(shù)值映射的過(guò)程如下:
2.@RequestParam注解參數(shù)
示例:
@RequestMapping("/test3") public String methodForRequestParam (@RequestParam Integer param){ System.out.println("RequestParam:"+JSON.toJSONString(param)); return ""; }
對(duì)應(yīng)的參數(shù)值處理類為RequestParamMethodArgumentResolver
參數(shù)映射的步驟如下:
1.1從request中獲取參數(shù)名對(duì)應(yīng)的值
1.2參數(shù)值類型轉(zhuǎn)換,從request中獲取的參數(shù)值為String,需要轉(zhuǎn)化為對(duì)應(yīng)Integer等類型。 spring-core提供了超級(jí)多的類型轉(zhuǎn)換工具,我截取了部分類:
Spring的強(qiáng)大不僅僅在它的設(shè)計(jì)思想,對(duì)各種復(fù)雜情況的支持,還有強(qiáng)大的代碼底層。
3.@RequestBody注解參數(shù)
示例:
@RequestMapping("/test6") public String methodForRequestBody (@RequestBody FamilyDTO familyDTO){ System.out.println("methodForNormalParam:"+JSON.toJSONString(familyDTO)); return ""; }
對(duì)應(yīng)的參數(shù)值處理類為:RequestResponseBodyMethodProcessor
參數(shù)映射的步驟如下:
1.1將body反序列化為對(duì)象
1.2如果類型為Optional,創(chuàng)建Optional類型對(duì)象
4.簡(jiǎn)單類型,無(wú)@RequestParam注解
示例:
@RequestMapping("/test5") public String methodForNormalParam (Integer param){ System.out.println("methodForNormalParam:"+JSON.toJSONString(param)); return ""; }
對(duì)于參數(shù)param,和帶有@RequestParam注解的參數(shù)一樣,使用 RequestParamMethodArgumentResolver類進(jìn)行參數(shù)值映射。
SpringMvc接口調(diào)用的核心方法invokeForRequest在InvocableHandlerMethod類中,大家有興趣,可以自己閱讀下源碼:
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { //從request中讀取,轉(zhuǎn)化參數(shù)值 Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); if (logger.isTraceEnabled()) { logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "' with arguments " + Arrays.toString(args)); } //方法的調(diào)用 Object returnValue = doInvoke(args); if (logger.isTraceEnabled()) { logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "] returned [" + returnValue + "]"); } return returnValue; }
總結(jié)
到此這篇關(guān)于SpringMvc參數(shù)值映射的文章就介紹到這了,更多相關(guān)SpringMvc參數(shù)值映射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot通用mapper和mybatis-generator代碼示例
這篇文章主要介紹了Springboot通用mapper和mybatis-generator代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12springboot項(xiàng)目如何設(shè)置session的過(guò)期時(shí)間
這篇文章主要介紹了springboot項(xiàng)目如何設(shè)置session的過(guò)期時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01java不同版本在多線程中使用隨機(jī)數(shù)生成器的實(shí)現(xiàn)
本文主要介紹了java不同版本在多線程中使用隨機(jī)數(shù)生成器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04eclipse連接數(shù)據(jù)庫(kù)并實(shí)現(xiàn)用戶注冊(cè)登錄功能
這篇文章主要介紹了eclipse連接數(shù)據(jù)庫(kù)并實(shí)現(xiàn)用戶注冊(cè)登錄功能的相關(guān)資料,需要的朋友可以參考下2021-01-01MyBatis緩存實(shí)現(xiàn)原理及代碼實(shí)例解析
這篇文章主要介紹了MyBatis緩存實(shí)現(xiàn)原理及代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08