如何将JSF页面呈现时间和响应大小插入页面本身,至少部分? [英] How to insert JSF page rendering time and response size into the page itself, at least partially?

查看:138
本文介绍了如何将JSF页面呈现时间和响应大小插入页面本身,至少部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我意识到这是一个鸡和蛋的问题,并且不可能准确地解决呈现页面所花费的时间(或响应的大小)并将该数字插入页面本身而不影响任何一个度量。不过,我正在寻找一种方法在JSF / Facelets / Seam应用程序的页面中部分插入任一数字。

I realize it's a chicken and egg problem and that it's not possible to accurately resolve the time it took to render a page (or the size of response) and insert that number into the page itself without affecting either measure. Nevertheless, I'm looking for a way to insert either number partially in a page of a JSF/Facelets/Seam application.

例如,在.jsf的底部页面某处:

E.g., at the bottom of a .jsf page somewhere:

<!-- page size: 10.3Kb -->
<!-- render time: 0.2s -->

我遇到了JSFUnit的 JSFTimer ,非常方便。但是,相位侦听器方法不允许将RENDER_RESPONSE阶段的结果插入到页面中。不知道如何访问到目前为止编码的响应的大小。

I've come across JSFUnit's JSFTimer, which is really handy. However, the phase listener approach doesn't allow the results of RENDER_RESPONSE phase to be inserted into the page. Not sure how to access the size of the response encoded so far either.

是否有一种快速而肮脏的方式来连接到某种类型的后处理事件在RENDER_RESPONSE结束之后将这两个数字注入到即将呈现的页面中?接近这个的一种方法可能是通过servlet过滤器,但我正在寻找更简单的东西;也许是Seam或Facelets的绝招...

Is there a quick and dirty way to hook up to some sort of post-processing event at or after the end of RENDER_RESPONSE and to inject both numbers into the page about to be rendered? One way of approaching this is perhaps through servlet filters, but I'm looking for something simpler; perhaps a trick with Seam or Facelets...

谢谢,

-A

Thanks,
-A

推荐答案

这是 Apache Commons IO 的完美用例 CountingOutputStream 。您需要创建一个 Filter ,它使用 HttpServletResponseWrapper 用这个替换响应的 OutputStream 替换 Writer 也应该包装包装的 OutputStream 。然后在请求范围内获取 HttpServletResponseWrapper 实例,以便从<$获取 getByteCount() C $ C> CountingOutputStream 。

This is a perfect use case for the Apache Commons IO CountingOutputStream. You need to create a Filter which uses HttpServletResponseWrapper to replace the OutputStream of the response with this one and replaces the Writer as well which should wrap the wrapped OutputStream. Then get hold of the HttpServletResponseWrapper instance in the request scope so that you can get the getByteCount() from the CountingOutputStream.

以下是 CountingFilter 的启动示例:

public class CountingFilter implements Filter {

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // NOOP.
    }

    @Override
    public void doFilter(ServletRequest request, final ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse httpres = (HttpServletResponse) response;
        CountingServletResponse counter = new CountingServletResponse(httpres);
        HttpServletRequest httpreq = (HttpServletRequest) request;
        httpreq.setAttribute("counter", counter);
        chain.doFilter(request, counter);
        counter.flushBuffer(); // Push the last bits containing HTML comment.
    }

    @Override
    public void destroy() {
        // NOOP.
    }

}

CountingServletResponse

public class CountingServletResponse extends HttpServletResponseWrapper {

    private final long startTime;
    private final CountingServletOutputStream output;
    private final PrintWriter writer;

    public CountingServletResponse(HttpServletResponse response) throws IOException {
        super(response);
        startTime = System.nanoTime();
        output = new CountingServletOutputStream(response.getOutputStream());
        writer = new PrintWriter(output, true);
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return output;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return writer;
    }

    @Override
    public void flushBuffer() throws IOException {
        writer.flush();
    }

    public long getElapsedTime() {
        return System.nanoTime() - startTime;
    }

    public long getByteCount() throws IOException {
        flushBuffer(); // Ensure that all bytes are written at this point.
        return output.getByteCount();
    }

}

CountingServletOutputStream

public class CountingServletOutputStream extends ServletOutputStream {

    private final CountingOutputStream output;

    public CountingServletOutputStream(ServletOutputStream output) {
        this.output = new CountingOutputStream(output);
    }

    @Override
    public void write(int b) throws IOException {
        output.write(b);
    }

    @Override
    public void flush() throws IOException {
        output.flush();
    }

    public long getByteCount() {
        return output.getByteCount();
    }

}

您可以在任何地方使用它(甚至非JSF)页面如下:

You can use it in any (even non-JSF) page as follows:

<!DOCTYPE html>
<html 
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Counting demo</title>
    </h:head>
    <h:body>
        <h1>Hello World</h1>
    </h:body>
</html>
<!-- page size: #{counter.byteCount / 1000}KB -->
<!-- render time: #{counter.elapsedTime / 1000000}ms -->

这篇关于如何将JSF页面呈现时间和响应大小插入页面本身,至少部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆