Servlets 提交HTTPServletResponse后写入outputStream

Servlets 提交HTTPServletResponse后写入outputStream,servlets,servlet-filters,Servlets,Servlet Filters,即使响应已提交,也可以将响应字节写入HTTPServletResponse的OutputStream吗? 我有一个Servlet过滤器,它通过调用doFilter将请求转发给CXFServlet。在doFilter之后,我显式地希望在OutputStream中写入字节。当前,在提交响应后写入OutputStream时,没有收到响应 public void doFilter(ServletRequest servletRequest, ServletResponse servlet

即使响应已提交,也可以将响应字节写入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) 如果您从
pw
接收到
byte[]bytes
中的内容(在该行上放置一个断点),这意味着过滤器和包装器完成了它们的工作,并且您的servlet(或其他内部过滤器)以某种方式关闭了真正的
响应。或者-尝试使用
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);
来自项目:

编辑

下面是我在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);
    }
}
}

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

您必须显示您的筛选器实现,因为提交响应只意味着状态代码和标题将被写入。@SotiriosDelimanolis:我已添加了筛选器实现。您是说客户端没有收到响应?你的日志怎么说?您可以调试以检查
字节
是否确实包含某些内容吗?是的。我想要的是,客户端应该在开始日志记录之前得到响应。当前客户端在日志记录过程完成后收到响应。您确定您的网络不仅速度慢,而且在日志记录后看到响应吗?