如何将JSF页面呈现时间和响应大小插入页面本身,至少部分?
我意识到这是一个鸡和蛋的问题,并且不可能准确地解决呈现页面所花费的时间(或响应的大小)并将该数字插入页面本身而不影响任何一个度量。 不过,我正在寻找一种方法来将一个数字部分插入JSF / Facelets / Seam应用程序的页面中。
例如,在某个地方的.jsf页面的底部:
我遇到过JSFUnit的JSFTimer ,非常方便。 但是,相位侦听器方法不允许将RENDER_RESPONSE阶段的结果插入到页面中。 不知道如何访问到目前为止编码的响应的大小。
在RENDER_RESPONSE结束时或之后是否有一种快速而肮脏的方式来连接某种后处理事件并将这两个数字注入到即将呈现的页面中? 接近这个的一种方法可能是通过servletfilter,但我正在寻找更简单的东西; 也许是Seam或Facelets的一招
谢谢,
-一个
这是Apache Commons IO CountingOutputStream
的完美用例。 您需要创建一个使用HttpServletResponseWrapper
的Filter
来替换响应的OutputStream
,并替换Writer
,它应该包装包装的OutputStream
。 然后在请求范围内获取HttpServletResponseWrapper
实例,以便从CountingOutputStream
获取getByteCount()
。
这是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)页面中使用它,如下所示:
Counting demo Hello World
我写了一篇博客文章,解释了如何创建一个拦截器来测量每个方法调用你的缝组件使用的方法。
你可以在这里找到博客文章。 您需要向下滚动到第二部分。
基本上,您需要做的就是使用@MeasureCalls
注释要测量的方法,它将被拦截器自动拾取
@Name("fooBean") @MeasureCalls public class FooBean
输出将是这样的,显示它花费的时间(以毫秒为单位)以及每个方法被调用的次数:
284.94 ms 1 FooBean.getRandomDroplets() 284.56 ms 1 GahBean.getRandomDroplets() 201.60 ms 2 SohBean.searchRatedDoodlesWithinHead() 185.94 ms 1 FroBean.doSearchPopular() 157.63 ms 1 FroBean.doSearchRecent() 42.34 ms 1 FooBean.fetchMostRecentYodel() 41.94 ms 1 GahBean.getMostRecentYodel() 15.89 ms 1 FooBean.getNoOfYodels() 15.00 ms 1 GahBean.getNoOfYodels() 9.14 ms 1 SohBean.mainYodels() 1.11 ms 2 SohBean.trackHoorayEvent() 0.32 ms 1 FroBean.reset() 0.22 ms 43 NohBean.thumbPicture() 0.03 ms 18 FooBean.getMostRecentYodels() 0.01 ms 1 NohBean.profilePicture() 0.01 ms 1 FroBean.setToDefault() 0.01 ms 1 FroBean.getRecentMarker()
或者有一个异步Javascript调用,它在服务器准备好之后从服务器获取响应时间和大小? 将其视为在页面加载完成后执行的回调,并且值已准备好插入。