request.getReader() 和 request.getInputStream() 都是只能調(diào)用一次,getReader() has already been called for t...

在 Filter 中對(duì) request 中的 body 進(jìn)行參數(shù)簽名校驗(yàn), 會(huì)報(bào)如下錯(cuò)誤:

getReader() has already been called for this request

原因是 request.getReader() 和 request.getInputStream() 都是只能調(diào)用一次

并且 getReader() 方法底層也是調(diào)用 getInputStream() 來(lái)實(shí)現(xiàn)的.

所以我們要使用 HttpServletRequestWrapper 來(lái)實(shí)現(xiàn)自定義的 CustomHttpServletRequestWrapper, 把 body 保存在 CustomHttpServletRequestWrapper 中, 并且重寫(xiě) getInputStream() 方法

重寫(xiě)? HttpServletRequestWrapper


package com.fosung.pb.village.config;

import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ReadListener;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

import java.io.BufferedReader;

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.nio.charset.StandardCharsets;

public class MyRequestWrapper extends HttpServletRequestWrapper {

? ? private byte[] body;

? ? public MyRequestWrapper(HttpServletRequest request) throws IOException {

? ? ? ? super(request);

? ? ? ? if(ServletFileUpload.isMultipartContent(request)){

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? StringBuilder sb = new StringBuilder();

? ? ? ? String line;

? ? ? ? BufferedReader reader = request.getReader();

? ? ? ? while ((line = reader.readLine()) != null) {

? ? ? ? ? ? sb.append(line);

? ? ? ? }

? ? ? ? String body = sb.toString();

? ? ? ? this.body = body.getBytes(StandardCharsets.UTF_8);

? ? }

? ? public String getBody() {

? ? ? ? return new String(this.body , StandardCharsets.UTF_8) ;

? ? }

? ? @Override

? ? public ServletInputStream getInputStream() {

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

? ? ? ? return new ServletInputStream() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean isFinished() {

? ? ? ? ? ? ? ? return false;

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public boolean isReady() {

? ? ? ? ? ? ? ? return false;

? ? ? ? ? ? }

? ? ? ? ? ? @Override

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

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public int read(){

? ? ? ? ? ? ? ? return bais.read();

? ? ? ? ? ? }

? ? ? ? };

? ? }

? ? @Override

? ? public BufferedReader getReader(){

? ? ? ? return new BufferedReader(new InputStreamReader(this.getInputStream()));

? ? }

}

package com.fosung.pb.village.config;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

/**

* @author lanx

* @date 2022/4/11

*/

@Slf4j

@Component

@WebFilter(filterName = "AntiSqlInjectionfilter", urlPatterns = "/*")

public class AntiSqlInjectionfilter implements Filter {

? ? public void destroy() {

? ? ? ? // TODO Auto-generated method stub

? ? }

? ? public void init(FilterConfig arg0) throws ServletException {

? ? ? ? // TODO Auto-generated method stub

? ? }

? ? public void doFilter(ServletRequest request, ServletResponse response,

? ? ? ? ? ? ? ? ? ? ? ? FilterChain chain) throws IOException, ServletException {

? ? ? ? HttpServletRequest req = (HttpServletRequest) request;

? ? ? ? HttpServletResponse res = (HttpServletResponse) response;

? ? ? ? MyRequestWrapper myRequestWrapper = null;

? ? ? ? // 獲取請(qǐng)求body

? ? ? ? try {

? ? ? ? ? ? myRequestWrapper = new MyRequestWrapper(req);

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? log.error("get request body exception", e);

? ? ? ? ? ? throw new RuntimeException(e);

? ? ? ? }

? ? ? ? if ("POST".equalsIgnoreCase(req.getMethod())) {

? ? ? ? ? ? String param = myRequestWrapper.getBody();

? ? ? ? ? ? chain.doFilter(myRequestWrapper, response);

? ? ? ? } else {

? ? ? ? ? ? chain.doFilter(myRequestWrapper, response);

? ? ? ? }

? ? }

}


原因是 request.getReader() 和 request.getInputStream() 都是只能調(diào)用一次。


原文鏈接:https://blog.csdn.net/woaiwojialanxi/article/details/124111799

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

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

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