java - Jetty:我如何使用 FilterHolder 来处理 "monitor"传入的 HTTP POST 请求内容?

标签 java http servlets post jetty

我试着做...

来源

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 替换为 InputStreamReader 根本不工作。

最佳答案

明白了!我正在分别为 InputStream 和 OutputStream 使用一个包装器。
已测试。适用于两个方向。

HttpRequestCopyFilter

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);
}
}

HttpResponseCopyFilter

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);
}
}

关于java - Jetty:我如何使用 FilterHolder 来处理 "monitor"传入的 HTTP POST 请求内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6925854/

相关文章:

java - Wildfly8/jBoss 包装 Logback 日志(双前缀)

http - 正常关闭 node.JS HTTP 服务器

javascript - 除非文本框有文本,否则如何限制按钮

java - 是否可以在 tomcat 中编辑类文件并重新编译该单个文件?

servlets - 使用 RequestDispatcher 将数据从 servlet 传递到另一个 servlet

java - 将错误处理从 JSP 替换为 Servlet

java - MongoDB列出java中可用的数据库

java - 如何在 Java 中使用 File.mkdirs() 编写优雅的代码?

java - 查找字符串中的子字符串(HTML、Android)

c++ - 我在 C++ 中的 http 服务器没有正确发送回所有文件