消費(fèi)了body中的流,@RequestBody映射不上了

springmvc

前幾天朋友找我,說遇到一個(gè)問題,在使用springboot開發(fā)的時(shí)候,json數(shù)據(jù)傳值但是后臺(tái)model映射不上,問我有沒有遇到這個(gè)問題。因?yàn)榭吹讲坏皆创a,只能靠猜測。便猜測了幾個(gè)原因??墒悄?都不對。

最后告訴我是被攔截器攔截了,突然意識到應(yīng)該是body中的流被消費(fèi)了。
攔截器呢是這么寫的。


image.png

后臺(tái)采用下圖的接收方式:


image.png

便讓我給分析下原因,正好有時(shí)間,我就還原了一下現(xiàn)場。

順便考慮下解決方案,代碼上傳到了github: https://github.com/topyuluo/question

先說第一個(gè)問題吧:攔截器中通過request.getInputStream()消費(fèi)了流中的數(shù)據(jù),而@RequestBody只能以流的方式讀取,流被讀過一次后,就不存在了,會(huì)導(dǎo)致后續(xù)無法處理。后臺(tái)會(huì)拋出此異常:

java.io.IOException: Stream closed

從網(wǎng)上找了一張圖,先看下springmvc的工作流程:

圖片來自網(wǎng)絡(luò).png

上圖是springmvc的整個(gè)執(zhí)行流程。已經(jīng)很清楚了,就不贅述了。

下面從源碼的層級來看下此異常的出處,先說一下異常產(chǎn)生的原因,我畫了一張圖。

image.png

@RequestBody ,是從InputStream中取值
@RequestParam ,是利用request.getParameterValues()來取值

解決方案:
既然找到了原因,對癥下藥就可以了,由于我們消費(fèi)了流,導(dǎo)致了流關(guān)閉,那么如果能將流拷貝一份或者向后臺(tái)在傳一份一模一樣的是否就解決了呢。
由于攔截器的特點(diǎn)不能實(shí)現(xiàn)這個(gè)需求,所以將攔截器替換為過濾器。

主要代碼如下:
request包裝類


request.png

response包裝類:


response.png

注冊過濾器:


register.png

過濾器中使用:


filter.png

這樣就可以在controller中使用@RequestBody接收了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 對于java中的思考的方向,1必須要看前端的頁面,對于前端的頁面基本的邏輯,如果能理解最好,不理解也要知道幾點(diǎn)。 ...
    神尤魯?shù)婪?/span>閱讀 896評論 0 0
  • SpringMVC介紹 Spring web mvc 和Struts2都屬于表現(xiàn)層的框架,它是Spring框架的一...
    day_Sunny閱讀 894評論 0 0
  • Getting Started Burp Suite 是用于攻擊web 應(yīng)用程序的集成平臺(tái)。它包含了許多工具,并為...
    Eva_chenx閱讀 29,232評論 0 14
  • 1:springMVC工作原理 【用戶發(fā)送請求到前端控制器dispatcherservlet,前端控制器接收到請求...
    行者和他的鋼筆閱讀 3,504評論 2 29
  • A1:自從我在社區(qū)居委會(huì)來工作之后,我就慢慢的發(fā)現(xiàn)我跟社區(qū)工作者是無法溝通,社區(qū)的工作非常的繁雜,每次當(dāng)我認(rèn)真...
    0c71bc12254a閱讀 364評論 0 0

友情鏈接更多精彩內(nèi)容