Servlets 提交HTTPServletResponse后写入outputStream
即使响应已提交,也可以将响应字节写入HTTPServletResponse的OutputStream吗? 我有一个Servlet过滤器,它通过调用doFilter将请求转发给CXFServlet。在doFilter之后,我显式地希望在OutputStream中写入字节。当前,在提交响应后写入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
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:我已添加了筛选器实现。您是说客户端没有收到响应?你的日志怎么说?您可以调试以检查字节是否确实包含某些内容吗?是的。我想要的是,客户端应该在开始日志记录之前得到响应。当前客户端在日志记录过程完成后收到响应。您确定您的网络不仅速度慢,而且在日志记录后看到响应吗?