如何将JSF页面呈现时间和响应大小插入页面本身,至少部分?

ani*_*tin 13 jsf servlets httpresponse

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

例如,在某个地方的.jsf页面的底部:

<!-- page size: 10.3Kb -->
<!-- render time: 0.2s -->
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢,
-A

Bal*_*usC 22

这是Apache Commons IO 的完美用例CountingOutputStream.您需要创建一个Filter它使用HttpServletResponseWrapper来代替OutputStream这一个响应并替换Writer以及应裹裹OutputStream.然后得到的保持HttpServletResponseWrapper实例在请求范围,使你可以得到getByteCount()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.
    }

}
Run Code Online (Sandbox Code Playgroud)

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();
    }

}
Run Code Online (Sandbox Code Playgroud)

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();
    }

}
Run Code Online (Sandbox Code Playgroud)

您可以在任何(甚至非JSF)页面中使用它,如下所示:

<!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 -->
Run Code Online (Sandbox Code Playgroud)