我试着做...
FilterHolder myHolder
= new FilterHolder(new Filter() {
public void init(FilterConfig fc) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain fc) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
// HERE:
InputStream is = httpReq.getInputStream();
// (read is to a string and output it, works,
// but swallows all data forever)
fc.doFilter(httpReq, httpResp);
}
public void destroy() {
}
});
...但是吞下所有数据并且真正的servlet没有得到任何东西。
我只是想“阅读” POST请求内容并将其输出以进行调试。
注1:我不想“拦截”请求,它们应该像以前一样经历。
注意2:另外一个提示,如何对 POST回复做同样的事情会非常友好。
编辑用Reader
替换InputStream
。 Reader
根本不起作用。
答案 0 :(得分:2)
知道了!我正在使用InputStream和OutputStream的包装器 的测试。适用于两个方向。
final class HttpRequestCopyFilter implements Filter {
private final OutputStream copyOutput;
public HttpRequestCopyFilter(OutputStream copyOutput) {
this.copyOutput = copyOutput;
}
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
private void flushCopy() throws IOException {
copyOutput.flush();
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain fc) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
HttpServletRequestWrapper requestWrapper =
new HttpServletRequestWrapper(httpReq) {
@Override
public ServletInputStream getInputStream()
throws IOException {
final ServletInputStream original =
super.getInputStream();
return new ServletInputStream() {
@Override
public int read() throws IOException {
int c = original.read();
if (c >= 0) {
copyOutput.write(c);
flushCopy();
}
return c;
}
@Override
public int read(byte[] b) throws IOException {
int count = original.read(b);
if (count >= 0) {
copyOutput.write(b, 0, count);
flushCopy();
}
return count;
}
@Override
public int read(byte[] b, int off, int len)
throws IOException {
int count = original.read(b, off, len);
if (count >= 0) {
copyOutput.write(b, off, count);
flushCopy();
}
return count;
}
};
}
};
fc.doFilter(requestWrapper, httpResp);
}
}
final class HttpResponseCopyFilter implements Filter {
private final OutputStream copyOutput;
public HttpResponseCopyFilter(OutputStream copyOutput) {
this.copyOutput = copyOutput;
}
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain fc) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
HttpServletResponseWrapper responseWrapper =
new HttpServletResponseWrapper(httpResp) {
@Override
public ServletOutputStream getOutputStream()
throws IOException {
final ServletOutputStream original =
super.getOutputStream();
return new ServletOutputStream() {
@Override
public void write(int b) throws IOException {
original.write(b);
copyOutput.write(b);
flush();
}
@Override
public void write(byte[] b) throws IOException {
original.write(b);
copyOutput.write(b);
flush();
}
@Override
public void write(byte[] b, int off, int len)
throws IOException {
original.write(b, off, len);
copyOutput.write(b, off, len);
flush();
}
@Override
public void flush() throws IOException {
original.flush();
copyOutput.flush();
super.flush();
}
@Override
public void close() throws IOException {
original.close();
copyOutput.flush(); // DON'T CLOSE COPY-OUTPUT !!!
super.close();
}
};
}
};
fc.doFilter(httpReq, responseWrapper);
}
}
答案 1 :(得分:0)
Servlet规范指出getInputStream
可能干扰例如getParameter(String name)
,请参阅this。因此,在调用getInputStream
之后,您可能无法使用请求对象的“更高级别”功能。
您可以配置Jetty's request logging并与TeeFilter
一起使用logback。它似乎实现了你需要的行为(从未使用过它)。
答案 2 :(得分:0)
鉴于posts将它们的key = value对存储在正文中,可以使用InputStream读取,你读取InputStream的行为可能会消耗它,这意味着当真正的servlet尝试检查它时IS是空的。