java 调用 request.getReader() 后重置 HttpRequest
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6322462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
resetting a HttpRequest after calling request.getReader()
提问by Noam Nevo
Is there a way to call the getReader()
method on a HttpRequest
and then "reset" the request so other calls to getReader()
will not throw java.lang.IllegalStateException
?
有没有办法在 a 上调用该getReader()
方法HttpRequest
然后“重置”请求,以便其他调用getReader()
不会抛出java.lang.IllegalStateException
?
采纳答案by Stephen C
The simple answer is "No".
简单回答是不”。
The stream is not resettable and there's no API method that will allow you to reopen it. (And for good reason. It would require the servlet infrastructure to keep a copy of the input just in casethe servlet decided to reopen the stream. That would be an unwarranted overhead.)
该流不可重置,并且没有允许您重新打开它的 API 方法。(并且有充分的理由。它需要 servlet 基础结构保留输入的副本,以防万一servlet 决定重新打开流。这将是无根据的开销。)
If you want to do this kind of thing, you will need to write your code to keep its own copy of the data. If you are implementing this in a Filter (or a Tomcat Valve) then you could create a HttpServletRequestWrapper
to hide the fact that you've already read the data .... as suggested by @Vineet.
如果你想做这种事情,你需要编写代码来保留自己的数据副本。如果您在过滤器(或 Tomcat Valve)中实现这一点,那么您可以创建一个HttpServletRequestWrapper
来隐藏您已经读取数据的事实......正如@Vineet所建议的那样。
回答by bmeding
Like other people have said, No I don't think there is a way to reset the request.
就像其他人所说的那样,不,我认为没有办法重置请求。
I have been in the same situation of wanting to log the content of the request in a ServletFilter before moving on. Here is a forum postthat helped me figure out how to create a HttpServletRequestWrapper
like Stephen C was talking about. That will store the data so you can call getReader()
and getInputStream()
multiple times.
在继续之前,我一直希望在 ServletFilter 中记录请求的内容。这是一个论坛帖子,它帮助我弄清楚如何创建HttpServletRequestWrapper
像 Stephen C 所说的那样。这将存储数据,以便您可以多次调用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();
}
}