3

即使提交了响应,是否可以将响应字节写入 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. 


}
4

1 回答 1

2

我看到两个可能的问题:

1)如果您byte[] bytespw(在该行放置一个断点)接收内容,这意味着过滤器和包装器完成了他们的工作,并且您的 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);
    }
}
}

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

于 2013-12-05T15:01:32.223 回答