關(guān)于post請求內(nèi)容無法重復(fù)獲取的解決方法
post請求體內(nèi)容無法重復(fù)獲取
為什么會無法重復(fù)讀取呢?
以tomcat為例,在進(jìn)行請求體讀取時實(shí)際底層調(diào)用的是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進(jìn)行讀取時
public int read(byte[] b, int off, int len) throws IOException {
// 如果流關(guān)閉,則拋出異常
if (closed) {
throw new IOException(sm.getString("inputBuffer.streamClosed"));
}
// 如果已經(jīng)讀完了,則返回-1
if (checkByteBufferEof()) {
return -1;
}
int n = Math.min(len, bb.remaining());
bb.get(b, off, n);
return n;
}
而流讀取完畢都會進(jìn)行close,這個流close之后,close狀態(tài)就置為了true,所以導(dǎo)致流無法進(jìn)行二次讀取
那么如何解決呢?將tomcat的Request類進(jìn)行重新實(shí)現(xiàn)嗎?代價太大了,sun公司當(dāng)初在設(shè)計(jì)的時候就已經(jīng)提供了解決方法,對于請求和響應(yīng),sun公司提供了包裝類,可以HttpServletRequestWrapper類包裝原始的request對象,實(shí)現(xiàn)了HttpServletRequest接口的所有方法,內(nèi)部調(diào)用了所包裝的request對象的對應(yīng)方法;相應(yīng)的也有HttpServletResponseWrapper類來包裝原始的response對象繼承HttpServletRequestWrapper來進(jìn)行方法重寫,可以使用HttpServletResponseWrapper和HttpServletRequestWrapper來進(jìn)行定制響應(yīng)和請求
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;
}
// 重寫讀取,從存儲的字節(jié)數(shù)組中讀
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
// 重寫讀取,從存儲的字節(jié)數(shù)組中讀
@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) {
}
};
}
}
到此這篇關(guān)于關(guān)于post請求內(nèi)容無法重復(fù)獲取的解決方法的文章就介紹到這了,更多相關(guān)post請求無法重復(fù)獲取內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中的構(gòu)造方法(構(gòu)造函數(shù))與普通方法區(qū)別及說明
這篇文章主要介紹了Java中的構(gòu)造方法(構(gòu)造函數(shù))與普通方法區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
Java接口統(tǒng)一樣式返回模板的實(shí)現(xiàn)
這篇文章主要介紹了Java接口統(tǒng)一樣式返回模板的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
關(guān)于Java中static關(guān)鍵字的用法
這篇文章主要介紹了關(guān)于Java中static關(guān)鍵字的用法,static:意為靜態(tài)的,在?Java?里面作為靜態(tài)修飾符,可以理解為全局的意思,static?不僅可以修飾成員變量,成員方法,還可以修飾代碼塊,需要的朋友可以參考下2023-08-08
SpringCloud之LoadBalancer負(fù)載均衡服務(wù)調(diào)用過程
這篇文章主要介紹了SpringCloud之LoadBalancer負(fù)載均衡服務(wù)調(diào)用過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
IntelliJ IDEA Run時報“無效的源發(fā)行版:16“錯誤問題及解決方法
這篇文章主要介紹了IntelliJ IDEA Run時報“無效的源發(fā)行版:16“錯誤問題及解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05
SpringBoot+Mybatis Plus導(dǎo)致PageHelper失效的解決方法
在Springboot項(xiàng)目中使用分頁插件的時候,發(fā)現(xiàn)PageHelper插件失效了 ,本文主要介紹了SpringBoot+Mybatis Plus導(dǎo)致PageHelper失效的解決方法,感興趣的可以了解一下2024-07-07

