Потоковое содержимое в пользовательский интерфейс JSF - PullRequest
1 голос
/ 15 марта 2010

Я был вполне доволен своим приложением JSF, которое считывало содержимое полученных сообщений MQ и передавало их в пользовательский интерфейс следующим образом:

<rich:panel>
<snip>
  <rich:panelMenuItem label="mylabel"  action="#{MyBacking.updateCurrent}">
    <f:param name="current" value="mylog.log" />    
  </rich:panelMenuItem>
</snip>
</rich:panel>

<rich:panel>
  <a4j:outputPanel ajaxRendered="true">
    <rich:insert content="#{MyBacking.log}" highlight="groovy" />
  </a4j:outputPanel>
</rich:panel>

и в MyBacking.java

private String logFile = null;
...

    public String updateCurrent() {
        FacesContext context=FacesContext.getCurrentInstance();
        setCurrent((String)context.getExternalContext().getRequestParameterMap().get("current"));
        setLog(getCurrent());
        return null;
    }

    public void setLog(String log) {
        sendMsg(log);
        msgBody = receiveMsg(moreargs);
        logFile = msgBody;
    }

    public String getLog() {
        return logFile;
    }

пока содержимое одного из сообщений не стало слишком большим, и кот не упал. Очевидно, я подумал, что мне нужно изменить способ его работы, чтобы я возвращал некоторую форму потока, чтобы ни один объект не становился настолько большим, чтобы контейнер умирал, а содержимое, возвращаемое последовательными сообщениями, передавалось в пользовательский интерфейс по мере его поступления.

Правильно ли я думаю, что могу заменить работу, которую я сейчас выполняю над объектом String, на объект BufferedOutputStream, т.е. без изменений в коде JSF и что-то вроде этого, изменяющееся на бэкэнде:

private BufferedOutputStream logFile = null;

    public void setLog(String log) {
        sendMsg(args);
        logFile = (BufferedOutputStream) receiveMsg(moreargs); 
    }

    public String getLog() {
        return logFile;
    }

1 Ответ

1 голос
/ 15 марта 2010

Если Tomcat упал, он должен иметь размер более 128 МБ или, возможно, удвоиться (что является минимальным объемом памяти по умолчанию для некоторых версий Tomcat). Я не думаю, что пользователи хотели бы посетить такую ​​большую веб-страницу. Может показаться, что он быстро работает как сервер и клиент на локальном хосте, но будет работать в 100 раз медленнее, когда обслуживается через интернет.

Введение пейджинга / фильтрации. Запросите и покажите только 100 записей одновременно. Добавьте фильтр, который возвращает конкретные результаты, такие как журналы определенного временного диапазона или определенного пользователя и т. Д.

Google также не показывает все миллионы доступных результатов сразу на одной веб-странице, их серверы также наверняка "упадут":)

Обновление согласно комментарию: компонент помещен в область действия сеанса или так? Таким образом, он действительно скоро накопится в памяти. Потоковая передача возможна только в том случае, если у вас есть InputStream на одной стороне и OutputStream на другой стороне. Невозможно преобразовать String в поток таким образом, как ваша попытка приведения, чтобы он больше не сохранялся в памяти Java. Источник должен оставаться на другой стороне, и он должен быть извлечен побайтно по строке. Единственно возможный подход - использовать <iframe>, чей src указывает на некоторый HttpServlet, который напрямую передает данные из источника в ответ.

Ваша лучшая ставка, скорее всего, состоит в том, чтобы хранить все это в базе данных или - если оно не содержит данных, специфичных для пользователя - в области приложения и делиться ими между всеми сеансами / запросами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...