Чому 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 МБ за сеанс користувача .