提交HTTPServletResponse后写入outputStream

时间:2013-10-03 11:08:20

标签: servlets servlet-filters

即使提交了Response,是否可以将响应字节写入HTTPServletResponse的OutputStream? 我有一个Servlet过滤器,通过调用doFilter将请求转发给CXFServlet。在doFilter之后,我明确地想在OutputStream中写入字节。目前,在提交响应后写入OutputStream时,我没有得到响应。

public void doFilter(ServletRequest servletRequest,
        ServletResponse servletResponse, FilterChain filterChain)
        throws IOException, ServletException {
    final HttpServletResponse response = (HttpServletResponse) servletResponse;

    final ByteArrayPrintWriter pw = new ByteArrayPrintWriter();
    HttpServletResponse wrappedResp = new HttpServletResponseWrapper(
            response) {
        public PrintWriter getWriter() {
            return pw.getWriter();
        }

        public ServletOutputStream getOutputStream() {
            return pw.getStream();
        }
    };
    filterChain.doFilter(servletRequest, wrappedResp);

    byte[] bytes = pw.toByteArray();
    response.getOutputStream().write(bytes);
    response.getOutputStream().flush();
    response.getOutputStream().close();

// Do logging after response is sent to client. 


}

1 个答案:

答案 0 :(得分:1)

我看到两个可能的问题:

1)如果从byte[] bytes收到pw中的内容(在该行放置一个断点),这意味着过滤器和包装器完成了他们的工作,而你的servlet(或其他内部过滤器)做了以某种方式关闭真实的response。或者 - 尝试使用Writer,我猜ByteArrayPrintWriter确实有一个返回char[]的方法,因此您可以使用response.getWriter()来编写内容。

2)如果byte[] bytes中没有内容,则ByteArrayPrintWriter无法正确收集内容。请注意,实现可能(或将)关闭响应编写器,因此ByteArrayPrintWriter的实现可能会关闭,这就是您没有获得任何内容的原因。

您还可以尝试以下操作:

BufferResponseWrapper wrappedResp = new BufferResponseWrapper(response);
filterChain.doFilter(request, wrappedResp);

// get buffered content
char[] chars = wrapper.getBufferContentAsChars();
// modify it somehow
chars = ArraysUtil.join(chars, "peep!".toCharArray());
// flush
wrapper.writeContentToResponse(chars);
来自Jodd项目的

BufferResponseWrapper.java

修改

以下是类似的过滤器,它在Tomcat上运行,仅使用Java类:

public class MyFilter implements Filter {

public void init(FilterConfig filterConfig) throws ServletException {
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final ByteArrayPrintWriter pw = new ByteArrayPrintWriter(baos);

    HttpServletResponse wrappedResp = new HttpServletResponseWrapper((HttpServletResponse) servletResponse) {
        @Override
        public PrintWriter getWriter() {
            return pw;
        }

        @Override
        public ServletOutputStream getOutputStream() {
            return new ServletOutputStream() {
                @Override
                public void write(int b) {
                    baos.write(b);
                }
            };
        }
    };

    filterChain.doFilter(servletRequest, wrappedResp);
    byte[] bytes = baos.toByteArray();
    servletResponse.getOutputStream().write(bytes);
}

public void destroy() {
}

public static class ByteArrayPrintWriter extends PrintWriter {
    public ByteArrayPrintWriter(OutputStream out) {
        super(out);
    }
}
}

请注意,这是一个快速而肮脏的实施,仅用于说明目的。