即使提交了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.
}
答案 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项目的
修改强>
以下是类似的过滤器,它在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);
}
}
}
请注意,这是一个快速而肮脏的实施,仅用于说明目的。