调用request.getReader()后重置HttpRequest

有没有办法在HttpRequest上调用getReader()方法然后“重置”请求,以便其他对getReader()调用不会抛出java.lang.IllegalStateException

简单回答是不”。

该流不可重置,并且没有API方法可以让您重新打开它。 (并且有充分的理由。它将要求servlet基础结构保留输入的副本, 以防 servlet决定重新打开流。这将是一个无根据的开销。)

如果您想要执行此类操作,则需要编写代码以保留其自己的数据副本。 如果你在Filter(或Tomcat Valve)中实现它,那么你可以创建一个HttpServletRequestWrapper来隐藏你已经读过数据的事实……正如@Vineet所建议的那样。

像其他人说的那样,不,我认为没有办法重置请求。

我一直处于想要在继续​​之前在ServletFilter中记录请求内容的情况。 这是一个论坛post ,帮助我弄清楚如何创建像Stephen C谈论的HttpServletRequestWrapper 。 这将存储数据,因此您可以getReader()调用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(); } } 
Interesting Posts