我正在研究一个java项目,现在我被要求跟踪向我们的服务器发送多少数据。所以我写了一个过滤器并将其映射到应该监视的所有调用,就像其他人告诉我的那样。这个过滤器可以正常工作,但是我在获取响应大小方面遇到了问题。这是我对doFilter的基本实现,我正在使用响应包装器。
的doFilter:
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
if (filterConfig == null)
return;
LogResponseWrapper logResponseWrapper = new LogResponseWrapper((HttpServletResponse) response);
chain.doFilter(request, logResponseWrapper);
}
Wrapper基于在线示例:
public class LogResponseWrapper extends HttpServletResponseWrapper
{
public long size = 0;
public PrintWriter myWriter = null;
public OutputStream myOutputStream = null;
LogResponseWrapper(HttpServletResponse response)
{
super(response);
}
@Override
public PrintWriter getWriter()
{
PrintWriter writer = null;
try
{
System.out.println("calling the writer");
writer = super.getWriter();
myWriter = writer;
}
catch (Exception e)
{
e.printStackTrace();
}
return writer;
}
@Override
public ServletOutputStream getOutputStream()
{
ServletOutputStream os = null;
try
{
System.out.println("calling the getOutputStream");
os = super.getOutputStream();
myOutputStream = os;
}
catch (Exception e)
{
e.printStackTrace();
}
return os;
}
}
所以,你知道,这是非常基本的,并做它应该做的事情。但是我似乎无法找到在调用chain.doFilter之后已将多少字节转移到响应中。我已经尝试将其转换为DataOutputStream和ByteArrayOutputStream,正如其他人所建议的那样,但这也无效。所以,如果有人对如何做到这一点有任何指示,请随时帮助我。
提前谢谢。
答案 0 :(得分:1)
让我们假设所有输出都是使用输出流完成的(不是很确定,也许编写器也可以直接写入)。然后你必须提供一个代理,实际上增加你的“大小”计数器。请注意,这可能会影响性能。
然后,您将返回new MyOutputStream(super.getOutputStream())
而不是super.getOutputStream()
,其中MyOutputStream是一个代理,可在关闭时更新总计。示例代码(警告:未测试):
private class MyOutputStream extends OutputStream {
private long written = 0;
private OutputStream inner;
public MyOutputStream(OutputStream inner) {
this.inner = inner;
}
public void close() {
inner.close();
updateTotals();
}
public void flush() {
inner.flush();
}
public void write(byte[] b) {
write(b, 0, b.length);
}
public void write(byte[] b, int off, int len) {
inner.write(b, off, len);
written += len;
}
public abstract void write(int b) {
written ++;
inner.write(b);
}
}
魔法在“updateTotals”中 - 您可以在此更新LogResponseWrapper的大小。如果要在多线程环境中执行,则应添加同步以避免竞争条件。