如何获取HttpServletResponse的总大小

4

我希望在一个servlet中监控响应大小,因此我计划添加过滤器来实现此功能。

但是当我查看HttpServletResponse方法时,我不知道如何获取响应大小:

response.getWriter()
response.getOutputStream()

有没有一种有效的方式来计算总响应大小?
5个回答

3
如果您可以访问响应头信息,您可以读取Content-Length。例如:
(Status-Line):HTTP/1.1 200 OK
Connection:Keep-Alive
Date:Fri, 10 Mar 2015 14:00:00 GMT
Content-Length:728

谢谢您的回复。我只是进行了一些调试,只能获取3个头信息。Content-Type|Transfer-Encoding|Date。在HttpServletResponse中找不到Content-Length。 - Bensson
@Bensson:如果既不是你的servlet也不是任何一个过滤器添加了该字段,则它不可能存在于响应中。 - Serge Ballesta
@SergeBallesta 就像你所说的那样,但是 content-length 没有随着实际大小自动更新。 - Bensson

2
您可以使用过滤器(Filter)为Servlet提供一个HttpServletResponseWrapper,该包装类将覆盖getWritergetOutputStream方法。这两个方法将返回实际流的包装类,以统计写入的字符数。

也许对于获取总大小来说有点太贵了。 - Bensson

2
反射编程,万岁。
    public static Long getByteCount(final HttpServletResponse response) {
    try {
        Field innerResponseField = ServletResponseWrapper.class.getDeclaredField("response");
        innerResponseField.setAccessible(true);
        innerResponseField.get(response);
        Object innerResponse = innerResponseField.get(response);
        Field contentWrittenField = OnCommittedResponseWrapper.class.getDeclaredField("contentWritten");
        contentWrittenField.setAccessible(true);
        return (Long) contentWrittenField.get(innerResponse);
    } catch (Exception e) {
        return null;
    }
}

在哪里可以获取到OnCommittedResponseWrapper呢? - user3217883
对我有用,不过我使用了contentWrittenField.get(response);内部对象innerResponse是不必要的。 - RichardK

1
你不需要自己监控这些基本的HTTP内容,Tomcat会为你完成:
AccessLogValve添加到你的server.xml文件中,然后你就可以在访问日志中使用%b变量来获取响应大小。

谢谢,实际上我想针对每个用户进行控制,所以我想在过滤器中处理此操作。在AccessLogValve中实现这一点确实很困难。 - Bensson

0

使用JavaEE API无法获取HttpServletRequest的总大小。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接