Почему JSF сохраняет состояние компонентов пользовательского интерфейса на сервере?

  1. До какого момента JSF сохраняет состояние компонентов пользовательского интерфейса на стороне сервера и когда именно информация о состоянии компонента пользовательского интерфейса удаляется из памяти сервера? Как зарегистрированный пользователь в приложении просматривает страницы, будет ли состояние компонентов продолжать накапливаться на сервере?

  2. Я не понимаю, в чем преимущество сохранения компонентов пользовательского интерфейса на сервере!? Не проходит ли передача данных с проверенными/преобразованными данными в управляемые компоненты? Могу я или я должен стараться избегать этого?

  3. Разве это не слишком много памяти на стороне сервера, если есть тысячи одновременных сеансов пользователя? У меня есть приложение, в котором пользователи могут публиковать блоги по определенным темам. Эти блоги довольно большие. Когда появится сообщение назад или запрос на просмотр блогов, будут ли эти большие данные страницы сохранены как часть состояния компонентов? Это будет слишком много памяти. Разве это не проблема?


Обновление 1:

Теперь больше не нужно сохранять состояние при использовании JSF. Для использования доступна высокопроизводительная реализация JSF без гражданства. См. Этот блог и этот вопрос для соответствующих деталей и обсуждения. Кроме того, есть открытая проблема для включения в спецификации JSF, возможность предоставления режима без состояния для JSF. (PS Рассмотрим голосования по вопросам этого и этого, если это полезная функция для вас.)


Обновление 2 (24-02-2013):

Отличная новость о том, что Mojarra 2.1.19 отсутствует в режиме без гражданства !

Глянь сюда:

http://weblogs.java.net/blog/mriem/archive/2013/02/08/jsf-going-stateless?force=255

http://java.net/jira/browse/JAVASERVERFACES-2731

http://balusc.blogspot.de/2013/02/stateless-jsf.html

Ответ 1

Почему JSF необходимо сохранить состояние компонентов пользовательского интерфейса на стороне сервера?

Поскольку HTTP является апатридом, а JSF является работоспособным. Дерево компонентов JSF подвержено динамическим (программным) изменениям. JSF просто нужно знать точное состояние, как это было, когда форма была показана конечному пользователю, чтобы она могла успешно обрабатывать весь жизненный цикл JSF на основе информации, предоставленной исходным деревом компонентов JSF, когда форма была отправлена ​​обратно сервер. В дереве компонентов содержится информация об именах параметров запроса, необходимых преобразователях/валидаторах, связанных свойствах управляемых bean и методах действий.


До какого момента JSF сохраняет состояние компонентов пользовательского интерфейса на стороне сервера и когда именно информация о состоянии компонента пользовательского интерфейса удаляется из памяти сервера?

Эти два вопроса, похоже, сводятся к одному и тому же. В любом случае, это специфичная реализация, а также зависит от того, сохраняется ли состояние на сервере или клиенте. Немного достойная реализация удалит его, когда он истек или когда очередь заполнена. Например, Mojarra имеет ограничение по умолчанию для 15 логических представлений, когда сохранение состояния установлено на сеанс. Это настраивается со следующим параметром контекста в web.xml:

<context-param>
    <param-name>com.sun.faces.numberOfLogicalViews</param-name>
    <param-value>15</param-value>
</context-param>

См. также FAQ Mojarra для других параметров, зависящих от Mojarra, и этот связанный ответ com.sun. faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews


Как вошедший в систему пользователь в приложении просматривает страницы, будет ли состояние компонентов продолжать накапливаться на сервере?

Технически это зависит от реализации. Если вы говорите о навигации по страницам (только GET-запросы), то Mojarra ничего не сохранит в сеансе. Если они, однако, POST-запросы (формы с командами/кнопками), то Mojarra сохранит состояние каждой формы в сеансе до максимального предела. Это позволяет enduser открывать несколько форм на разных вкладках браузера в том же сеансе.

Или, когда для сохранения состояния установлено клиенту, JSF ничего не будет хранить в сеансе. Вы можете сделать это с помощью следующего параметра контекста в web.xml:

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

Затем он будет сериализован для зашифрованной строки в скрытом поле ввода с именем javax.faces.ViewState формы.


Я не понимаю, какая польза от сохранения состояния компонента пользовательского интерфейса на стороне сервера. Не передается ли непосредственно проверенные/преобразованные данные в управляемый beans? Могу ли я попытаться избежать этого?

Этого недостаточно для обеспечения целостности и надежности JSF. JSF - это динамическая структура с единой точкой входа. Без управления состоянием можно было бы обманывать/обрабатывать HTTP-запросы определенным образом (например, манипулировать атрибутами disabled, readonly и rendered), чтобы JSF делал разные - и потенциально опасные вещи. Это было бы даже подвержено атакам CSRF и фишингу.


И не будет ли это потреблять слишком много памяти на стороне сервера, если есть тысячи одновременных сеансов пользователя? У меня есть приложение, в котором пользователи могут публиковать блоги по определенным темам. Эти блоги довольно большие. Когда появится сообщение или запрос на просмотр блогов, большие блоги будут сохранены как часть состояния компонентов. Это поглотит слишком много памяти. Разве это не проблема?

Память особенно дешевая. Просто дайте приложениям достаточно памяти. Или, если пропускная способность сети дешевле для вас, просто переключите сохранение состояния на клиентскую сторону. Чтобы найти наилучшее совпадение, просто выполните stresstest и профилируйте ваш webapp с ожидаемым максимальным количеством одновременных пользователей, а затем дайте серверу приложений 125% ~ 150% максимальной измеренной памяти.

Обратите внимание, что JSF 2.0 значительно улучшил управление состоянием. Можно сохранить частичное состояние (например, только <h:form> будет сохранен вместо всего материала от <html> до конца). Моджарра, например, делает это. Средняя форма с 10 полями ввода (каждая с меткой и сообщением) и 2 кнопками занимает не более 1 КБ. С 15 просмотров в сеансе, это должно быть не более 15 КБ за сеанс. При ~ 1000 одновременных сеансов пользователя это должно быть не более 15 МБ.

Вы должны сосредоточиться на реальных объектах (управляемых beans и/или даже сущностях DB) в области сеанса или приложения. Я видел много кодов и проектов, которые излишне дублируют всю таблицу базы данных в Java-память в аромате сеанса scope bean, где Java используется вместо SQL для фильтрации/группировки/организации записей. С ~ 1000 записей, которые будут легко проходить через 10 МБ на сеанс пользователя.