在调用 request.getReader() 后重置 HttpRequest
2022-09-04 08:22:35
有没有办法在 a 上调用该方法,然后“重置”请求,以便其他调用不会抛出?getReader()
HttpRequest
getReader()
java.lang.IllegalStateException
有没有办法在 a 上调用该方法,然后“重置”请求,以便其他调用不会抛出?getReader()
HttpRequest
getReader()
java.lang.IllegalStateException
就像其他人说的,不,我认为没有办法重置请求。
在继续之前,我一直处于相同的情况,希望在ServletFilter中记录请求的内容。这是一个论坛帖子,帮助我弄清楚如何创建一个像Stephen C所说的那样。这将存储数据,以便您可以多次调用和。HttpServletRequestWrapper
getReader()
getInputStream()
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class MyRequestWrapper extends HttpServletRequestWrapper {
private HttpServletRequest original;
private byte[] reqBytes;
private boolean firstTime = true;
public MyRequestWrapper(HttpServletRequest request) {
super(request);
original = request;
}
@Override
public BufferedReader getReader() throws IOException{
if(firstTime)
firstTime();
InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(reqBytes));
return new BufferedReader(isr);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if(firstTime)
firstTime();
ServletInputStream sis = new ServletInputStream() {
private int i;
@Override
public int read() throws IOException {
byte b;
if(reqBytes.length > i)
b = reqBytes[i++];
else
b = -1;
return b;
}
};
return sis;
}
private void firstTime() throws IOException{
firstTime = false;
StringBuffer buffer = new StringBuffer();
BufferedReader reader = original.getReader();
String line;
while((line = reader.readLine()) != null){
buffer.append(line);
}
reqBytes = buffer.toString().getBytes();
}
}
简单的答案是“不”。
该流不可重置,并且没有 API 方法允许您重新打开它。(这是有充分理由的。它需要 servlet 基础结构保留输入的副本,以防 servlet 决定重新打开流。这将是一个不必要的开销。
如果你想做这种事情,你需要编写你的代码来保留它自己的数据副本。如果您在过滤器(或Tomcat Valve)中实现此功能,那么您可以创建一个来隐藏您已经读取数据的事实....正如@Vineet所建议的那样。HttpServletRequestWrapper