post請求體內容無法重復獲取

post請求體內容無法重復獲取

為什么會無法重復讀取呢?

以tomcat為例,在進行請求體讀取時實際底層調用的是org.apache.catalina.connector.Request的getInputStream()方法,而該方法返回的是CoyoteInputStream輸入流

public?ServletInputStream?getInputStream()?throws?IOException?{

????if?(usingReader)?{
????????throw?new?IllegalStateException(sm.getString("coyoteRequest.getInputStream.ise"));
????}

????usingInputStream?=?true;
????if?(inputStream?==?null)?{
????????inputStream?=?new?CoyoteInputStream(inputBuffer);
????}
????return?inputStream;

}

在使用CoyoteInputStream進行讀取時

public?int?read(byte[]?b,?int?off,?int?len)?throws?IOException?{
??//?如果流關閉,則拋出異常
????if?(closed)?{
????????throw?new?IOException(sm.getString("inputBuffer.streamClosed"));
????}
//?如果已經讀完了,則返回-1
????if?(checkByteBufferEof())?{
????????return?-1;
????}
????int?n?=?Math.min(len,?bb.remaining());
????bb.get(b,?off,?n);
????return?n;
}

而流讀取完畢都會進行close,這個流close之后,close狀態就置為了true,所以導致流無法進行二次讀取

那么如何解決呢?將tomcat的Request類進行重新實現嗎?代價太大了,sun公司當初在設計的時候就已經提供了解決方法,對于請求和響應,sun公司提供了包裝類,可以HttpServletRequestWrapper類包裝原始的request對象,實現了HttpServletRequest接口的所有方法,內部調用了所包裝的request對象的對應方法;相應的也有HttpServletResponseWrapper類來包裝原始的response對象繼承HttpServletRequestWrapper來進行方法重寫,可以使用HttpServletResponseWrapper和HttpServletRequestWrapper來進行定制響應和請求

public?class?BodyReaderHttpServletRequestWrapper?extends?HttpServletRequestWrapper?{
??//?存儲請求體
????private?byte[]?body;

????private?HttpServletRequest?orgRequest;

????public?BodyReaderHttpServletRequestWrapper(HttpServletRequest?request)?throws?IOException?{
????????super(request);
????????this.orgRequest?=?request;
????????body?=?HttpHelper.getBody(request);
????}

????public?HttpServletRequest?getOrgRequest()?{
????????return?this.orgRequest;
????}

??//?重寫讀取,從存儲的字節數組中讀
????@Override
????public?BufferedReader?getReader()?throws?IOException?{
????????return?new?BufferedReader(new?InputStreamReader(getInputStream()));
????}

??//?重寫讀取,從存儲的字節數組中讀
????@Override
????public?ServletInputStream?getInputStream()?throws?IOException?{

????????final?ByteArrayInputStream?bais?=?new?ByteArrayInputStream(body);

????????return?new?ServletInputStream()?{

????????????@Override
????????????public?int?read()?throws?IOException?{
????????????????return?bais.read();
????????????}

????????????@Override
????????????public?boolean?isFinished()?{
????????????????return?false;
????????????}

????????????@Override
????????????public?boolean?isReady()?{
????????????????return?false;
????????????}

????????????@Override
????????????public?void?setReadListener(ReadListener?readListener)?{

????????????}
????????};
????}
}

https://zhhll.icu/2020/javaweb/問題/6.post請求體內容無法重復獲取/

本文由 mdnice 多平臺發布

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716806.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716806.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716806.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CVE-2016-5195 復現記錄

文章目錄 poc前置知識頁表與缺頁異常/proc/self/mem的寫入流程madvise 漏洞點修復 Dirty COW臟牛漏洞是一個非常有名的Linux競爭條件漏洞,雖然早在2016年就已經被修復,但它依然影響著眾多古老版本的Linux發行版,如果需要了解Linux的COW&#…

Redis7 實現持久化的三種方式

1、概述 1.1、Redis持久化的重要性 數據恢復:Redis是一個內存數據庫,如果系統或服務宕機,內存中的數據將會丟失。Redis的持久化機制可以把數據保存到磁盤上,以便在系統重啟后恢復數據。這是Redis持久化最基本也是最重要的功能。…

JCL中IEFBR14和COND

JCL中IEFBR14和COND ? COND CODE,就是反映JCL中STEP運行狀態的參數,JCL正常終了的COND CODE 是0000,另外筆者在執行某些工具JCL時候,比方說簡單一個COMPARE吧,可能會出現0012、0004或者0016,0001&#xf…

JSON與Object等的相互轉換

JSON與Object的轉換 // 將 Object 對象轉換為 String 類型 String jsonString = JSON.toJSONString(body);// 將 String 或 byte[] 轉換為 JSONObject 類型 JSONObject jsonObject = JSONObject.parseObject(jsonString); // 根據鍵key獲取 JSONObject 中的某一個鍵值對的值 S…

數據結構:棧和隊列的實現附上源代碼(C語言版)

目錄 前言 1.棧 1.1 棧的概念及結構 1.2 棧的底層數據結構選擇 1.2 數據結構設計代碼(棧的實現) 1.3 接口函數實現代碼 (1)初始化棧 (2)銷毀棧 (3)壓棧 (4&…

金三銀四求職攻略:如何在面試中脫穎而出

隨著春天的腳步漸近,對于眾多程序員來說,一年中最繁忙、最重要的時期也隨之而來。金三銀四,即三月和四月,被廣大程序員視為求職的黃金時段。在這段時間里,各大公司紛紛開放招聘,求職者們則通過一場又一場的…

初階數據結構之---棧和隊列(C語言)

引言 在順序表和鏈表那篇博客中提到過,棧和隊列也屬于線性表 線性表: 線性表(linear list)是n個具有相同特性的數據元素的有限序列。 線性表是一種在實際中廣泛使用的數據結構。線性表在邏輯上是線性結構,也就是說是連…

xxl-job--02--可視化界面各功能詳細介紹

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 可視化界面1 新增執行器2.新增任務**執行器**:**任務描述**:**路由策略**:**Cron**:cron表達式**運行模式**JobHandl…

01.18 校招 實習 內推 面經

綠*泡*泡VX: neituijunsir 交流*裙 ,內推/實習/校招匯總表格 1、校招 | 中國航天科工四院四部2024春季校園招聘 校招 | 中國航天科工四院四部2024春季校園招聘 2、阿里集團24屆秋招「空缺崗位」大盤點 校招 | 阿里集團24屆校招補錄大盤點&#xff0…

全量知識系統問題及SmartChat給出的答復 之15 幣圈生態鏈

Q40. 今天聊聊關于幣圈和幣圈生態方面,尤其是在建立和保護各種幣圈生態鏈的問題。 主要包括各種主體、 各種權益 和 各種幣及其幣圈的 分類,包括 概念、關系和 鏈接和斷鏈的判斷根據等等, 是否有一個比較清晰的體系結構呢? 因為現…

java Springboot vue 健身房系統,簡單練手項目

該項目主要分為管理員和會員模塊 管理員具有:會員管理,器材管理,員工管理,健身課程管理 會員模塊,可以在線報名健身課程,查看自己課程 采用VUE前端開發和springboot后端開發,極簡代碼編寫,沒…

融資項目——登錄接口的開發

1. 首先創建登錄與用戶信息VO類。 Data ApiModel(description "登陸對象") public class LoginVO {ApiModelProperty("手機號")private String mobile;ApiModelProperty("密碼")private String password;ApiModelProperty("用戶類型"…

藍橋每日一題 (差分)3月3號

//3279改變數組元素 自己做TLE&#xff1a;奈何想不出怎么用差分 #include<bits/stdc.h> using namespace std; //3279 改變數組元素&#xff08;超時&#xff09; const int N2e510; vector<int>a; int t,n; int main() {cin>>t;while(t--){cin>>n;…

ubuntu20.04安裝docker及運行

ubuntu20.04安裝docker及運行 ubuntu環境版本 Ubuntu Focal 20.04 (LTS) 查看系統版本 rootubuntu20043:~# cat /proc/version Linux version 5.15.0-78-generic (builddlcy02-amd64-008) (gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0, GNU ld (GNU Binutils for Ubuntu) …

Vue(黑馬學習筆記)

Vue概述 通過我們學習的htmlcssjs已經能夠開發美觀的頁面了&#xff0c;但是開發的效率還有待提高&#xff0c;那么如何提高呢&#xff1f;我們先來分析下頁面的組成。一個完整的html頁面包括了視圖和數據&#xff0c;數據是通過請求從后臺獲取的那么意味著我們需要將后臺獲取…

通過XML調用CAPL腳本進行測試(新手向)

目錄 0 引言 1 XML簡介 2 通過XML調用CAPL腳本 0 引言 紀念一下今天這個特殊日子&#xff0c;四年出現一次的29號。 在CANoe中做自動化測試常用的編程方法有CAPL和XML兩種&#xff0c;二者各有各的特色&#xff0c;對于CAPL來說新手肯定是更熟悉一些&#xff0c;因為說到在C…

使用Go Validator在Go應用中有效驗證數據

作為一名開發者&#xff0c;確保Go應用中處理的數據是有效和準確的非常重要。Go Validator是一個開源的數據驗證庫&#xff0c;為Go結構體提供強大且易于使用的數據驗證功能。本篇文章將介紹Go Validator庫的主要特點以及如何在Go應用中使用它來有效驗證數據。 什么是Go Valid…

Vue開發實例(五)修改項目入口頁面布局

修改項目入口 一、創建新入口二、分析代碼&#xff0c;修改入口三、搭建項目主頁面布局1、Container 布局容器介紹2、創建布局3、布局器鋪滿屏幕4、創建Header頁面5、加入Aside、Main和Footer模塊 一、創建新入口 創建新的入口&#xff0c;取消原來的HelloWorld入口 參考代碼…

劍指offer刷題記錄Day2 07.數組中重復的數字 ---> 11.旋轉數組的最小數字

名人說&#xff1a;莫道桑榆晚&#xff0c;為霞尚滿天。——劉禹錫&#xff08;劉夢得&#xff0c;詩豪&#xff09; 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; 目錄 1、重建二叉樹①代碼實現&#xff08;帶注釋&am…

【重溫設計模式】職責鏈模式及其Java示例

職責鏈模式的介紹 在開發過程中&#xff0c;我們經常會遇到這樣的問題&#xff1a;一個請求需要經過多個對象的處理&#xff0c;但是我們并不知道具體由哪個對象來處理&#xff0c;或者說&#xff0c;我們希望由接收到請求的對象自己去決定如何處理或者是將請求傳遞給下一個對…