Как вставить размер ответа и время в саму страницу по крайней мере частично?

Я понимаю, что это - проблема курицы и яйца и что не возможно точно разрешить время, которое потребовалось, чтобы представить страницу (или размер ответа) и вставить то число в саму страницу, не влияя ни на одну меру. Тем не менее, я ищу способ вставить любое число частично в страницу JSF/Facelets/Seam приложения.

Например, у основания .jsf страницы где-нибудь:



Я столкнулся с JSFTimer JSFUNIT, который действительно удобен. Однако подход слушателя фазы не позволяет результатам фазы RENDER_RESPONSE быть вставленными в страницу. Не уверенный, как получить доступ к размеру ответа, закодированного до сих пор также.

Существует ли быстрый и грязный способ сцепиться до своего рода события последующей обработки в или после конца RENDER_RESPONSE и ввести оба числа в страницу, собирающуюся быть представленным? Один способ приблизиться к этому, возможно, через фильтры сервлета, но я ищу что-то более простое; возможно, прием с Seam или Facelets...

Спасибо,
- A

13
задан BalusC 3 May 2019 в 09:11
поделиться

2 ответа

Это идеальный случай использования 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.
    }

}

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

}

The 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) странице следующим образом:

<!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 -->
22
ответ дан 1 December 2019 в 21:51
поделиться

Или у вас есть вызов Asynch Javascript, который получает время отклика и размер от сервера после его готовности? Относитесь к нему как к обратному вызову, который будет выполнен после загрузки страницы и готовности значений к вставке.

0
ответ дан 1 December 2019 в 21:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: