请问Http servlet请求在读取一次后会丢失来自POST主体的Params

Http servlet请求在读取一次后会丢失来自POST主体的Params

我试图访问Javaservlet过滤器中的两个http请求参数,这里没有什么新的,但是惊讶地发现这些参数已经被消耗了!因此,它在过滤器链中不再可用。

似乎只有当参数出现在POST请求体(例如表单提交)中时才会发生这种情况。

有没有办法读取参数而不消耗它们?

到目前为止,我只找到了这个引用:使用request.get参量的servlet筛选器丢失表单数据.

谢谢!


幕布斯6054654
浏览 553回答 3
3回答

杨__羊羊

我知道我迟到了,但这个问题仍然与我有关,所以这篇文章是谷歌最热门的文章之一。我将继续发布我的解决方案,希望其他人能节省几个小时。在我的例子中,我需要用它们的身体记录所有请求和响应。使用SpringFramework答案其实很简单,只需使用ContentCachingRequestWrapper和感应器.import org.springframework.web.util.ContentCachingRequestWrapper;import org.springframework.web.util.ContentCachingResponseWrapper; import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse; import java.io.IOException;public class LoggingFilter implements Filter {     @Override     public void init(FilterConfig filterConfig) throws ServletException {     }     @Override     public void destroy() {     }     @Override     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)             throws IOException, ServletException {         ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);         ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response);         try {             chain.doFilter(requestWrapper, responseWrapper);         } finally {             String requestBody = new String(requestWrapper.getContentAsByteArray());             String responseBody = new String(responseWrapper.getContentAsByteArray());             // Do not forget this line after reading response content or actual response will be empty!             responseWrapper.copyBodyToResponse();             // Write request and response body, headers, timestamps etc. to log files         }     }}

白衣非少年

唯一的方法是自己在过滤器中使用整个输入流,从其中获取所需的内容,然后为所阅读的内容创建一个新的InputStream,并将InputStream放入ServletRequestWrapper(或HttpServletRequestWrapper)。缺点是,您必须自己解析有效负载,标准不允许您使用该功能。增编正如我所说的,您需要查看HttpServletRequestWrapper。在过滤器中,继续调用FilterChain.doFilter(请求、响应)。对于简单的过滤器,请求和响应与传递给过滤器的请求和响应相同。不必是这样的。您可以用自己的请求和/或响应替换这些请求。HttpServletRequestWrapper是专门为这一目的而设计的。将原始请求传递给它,然后就可以拦截所有的呼叫。您将创建自己的子类,并将getInputStream方法替换为您自己的方法之一。您不能更改原始请求的输入流,因此可以使用这个包装器并返回您自己的输入流。最简单的情况是在字节缓冲区中使用原始请求输入流,在它上执行您想要的任何魔术,然后从该缓冲区创建一个新的ByteArrayInputStream。这就是在包装器中返回的内容,它被传递给FilterChain.doFilter方法。您需要子类ServletInputStream,并为ByteArrayInputStream编写另一个包装器,但这也不是什么大事。
打开App,查看更多内容
随时随地看视频慕课网APP