Чому JSF зберігає стан компонентів інтерфейсу на сервері?


108
  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

Відповіді:


199

Чому JSF потрібно зберегти стан компонентів інтерфейсу на стороні сервера?

Тому що HTTP не має статусу, а JSF є статтю. Дерево компонентів JSF може зазнавати динамічних (програмних) змін. JSF просто повинен знати точний стан, як це було, коли форма була показана ендузеру, щоб він міг успішно обробляти весь життєвий цикл JSF на основі інформації, наданої оригінальним деревом компонентів JSF, коли форма повертається назад до сервер. Дерево компонентів надає інформацію про назви параметрів запиту, необхідні перетворювачі / валідатори, властивості пов'язаного керованого боба та методи дії.


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

Ці два питання, схоже, зводяться до одного і того ж. У будь-якому випадку, це конкретна реалізація, а також залежить від збереження стану на сервері чи клієнті. Трохи пристойна реалізація видалить її після закінчення терміну чи після заповнення черги. Наприклад, у Mojarra встановлено обмеження за умовчанням у 15 логічних переглядів, коли збереження стану встановлено на сеанс. Це налаштовується за допомогою наступного контексту в параметрі web.xml:

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

Перегляньте також поширені запитання про Mojarra щодо інших параметрів, характерних для монарри, і відповідь на цю відповідь com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews


Оскільки користувач, який увійшов у програму, переглядає сторінки, чи буде стан компонентів накопичуватися на сервері?

Технічно це залежить від реалізації. Якщо ви говорите про навігацію зі сторінки на сторінку (лише GET запити), то Mojarra нічого не збереже в сеансі. Якщо вони є POST-запитами (форми з командними посиланнями / кнопками), то Mojarra збереже стан кожної форми в сеансі до максимального обмеження. Це дозволяє кінцевому користувачеві відкривати кілька форм на різних вкладках браузера за один сеанс.

Або, коли для економії стану встановлено клієнт, JSF нічого не зберігатиме у сеансі. Це можна зробити за допомогою наступного контекстного парама в web.xml:

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

Потім він буде серіалізований до зашифрованого рядка в прихованому полі введення з назвою javax.faces.ViewStateформи.


Я не розумію, яка вигода від збереження стану компонента інтерфейсу на стороні сервера. Чи недостатньо безпосередньо передачі перевірених / перетворених даних у керовані боби? Чи можу я / намагаюся уникати цього?

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


І чи не буде ця потреба занадто багато пам’яті на стороні сервера, якщо є тисячі одночасних сеансів користувача? У мене є додаток, де користувачі можуть розміщувати блоги на певні теми. Ці блоги мають досить великі розміри. Коли буде опубліковано повідомлення або запит на перегляд блогів, великі блоги будуть збережені як частина стану компонентів. Це би зайняло занадто багато пам'яті. Це не стурбованість?

Пам'ять особливо дешева. Просто дайте програмі достатньо пам’яті. Або якщо пропускна здатність мережі вам дешевша, просто переключіть економію стану на сторону клієнта. Щоб знайти найкращу відповідність, просто підкресліть і профайлюйте свій веб-сайт із очікуваною максимальною кількістю одночасних користувачів, а потім дайте програмі 125% ~ 150% максимально виміряної пам'яті.

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

Ваша стурбованість повинна бути більше зосереджена на реальних об'єктах (керованих бобах та / або навіть об'єктах БД) у межах сеансу чи програми. Я бачив безліч кодів і проектів, які надмірно копіюють всю таблицю баз даних в пам'ять Java на смак бобового діапазону сеансів, де Java використовується замість SQL для фільтрації / групування / упорядкування записів. Маючи ~ 1000 записів, це може легко перевищити 10 МБ за сеанс користувача .


1
Чи можете ви уточнити №2? Чому не можна відтворити дерево компонентів у кожному запиті? Який стан насправді потрібно зберігати між запитами та чому? Здається, що єдиною причиною збереження компонентного дерева між запитами буде ефективність.
Райан

Більш сфокусоване запитання тут: stackoverflow.com/questions/7349174/…
Райан,

Ваша відповідь була для мене дуже зрозумілою! Питання щодо продуктивності та масштабованості JSF мають суттєве відношення до реалізації програміста! Потрібно знати, як правильно використовувати технологію!
Лукас Батістуссі,

"Просто дайте програмі достатньо пам'яті." Е-э, у мене складається враження, що ми говоримо тут на рівні підприємств, якщо ми говоримо про тисячі сеансів одночасного користування. Якщо у вас є обладнання на рівні підприємства, ви не можете просто «надати достатньому обсягу пам’яті додатку», як можна в домашньому вікні Linux.
Ст

Ваша відповідь була дуже чіткою і за це дякую. Чому обсяг спалаху JSF зник, якщо встановити javax.face.PARTIAL_STATE_SAVING на true. getFacesContext (). getExternalContext (). getFlash (). put ("buildingId", buildingId).
Травень
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.