Warum speichert JSF den Status von UI-Komponenten auf dem Server?


108
  1. Bis zu welchem ​​Zeitpunkt speichert JSF den Status von UI-Komponenten auf der Serverseite und wann genau werden die Statusinformationen der UI-Komponente aus dem Serverspeicher entfernt? Wenn sich ein angemeldeter Benutzer in der Anwendung durch Seiten navigiert, wird sich der Status der Komponenten weiterhin auf dem Server ansammeln?

  2. Ich verstehe nicht, welchen Vorteil es hat, den Status der UI-Komponenten auf dem Server beizubehalten! Reicht es nicht aus, die validierten / konvertierten Daten direkt an verwaltete Beans zu übergeben? Kann oder sollte ich versuchen, es zu vermeiden?

  3. Verbraucht das nicht zu viel Speicher auf der Serverseite, wenn Tausende von Benutzersitzungen gleichzeitig stattfinden? Ich habe eine Anwendung, in der Benutzer Blogs zu bestimmten Themen veröffentlichen können. Diese Blogs sind ziemlich groß. Werden diese großen Seitendaten als Teil des Status der Komponenten gespeichert, wenn ein Postback oder eine Anforderung zum Anzeigen der Blogs erfolgt? Dies würde zu viel Speicher verschlingen. Ist das nicht ein Problem?


Update 1:

Jetzt ist es nicht mehr erforderlich, den Status während der Verwendung von JSF zu speichern. Eine leistungsstarke zustandslose JSF-Implementierung steht zur Verfügung. In diesem Blog und in dieser Frage finden Sie relevante Details und Diskussionen. Es gibt auch ein offenes Problem , das in JSF-Spezifikationen aufgenommen werden kann, eine Option, um den zustandslosen Modus für JSF bereitzustellen. (PS: Erwägen Sie, für die Themen this und this zu stimmen, wenn dies eine nützliche Funktion für Sie ist.)


Update 2 (24-02-2013):

Eine gute Nachricht, dass Mojarra 2.1.19 im staatenlosen Modus ist !

Siehe hier:

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

Antworten:


199

Warum muss JSF den Status von UI-Komponenten auf der Serverseite speichern?

Weil HTTP zustandslos und JSF statusbehaftet ist. Der JSF-Komponentenbaum unterliegt dynamischen (programmatischen) Änderungen. JSF muss lediglich den genauen Status kennen, in dem das Formular dem Endbenutzer angezeigt wurde, damit es den gesamten JSF-Lebenszyklus basierend auf den Informationen des ursprünglichen JSF-Komponentenbaums, an den das Formular zurückgesendet wurde, erfolgreich verarbeiten kann der Kellner. Der Komponentenbaum enthält Informationen zu den Anforderungsparameternamen, den erforderlichen Konvertern / Validatoren, den Eigenschaften der gebundenen verwalteten Bean und den Aktionsmethoden.


Bis zu welchem ​​Zeitpunkt speichert JSF den Status der UI-Komponenten auf der Serverseite und wann genau werden die Statusinformationen der UI-Komponente aus dem Serverspeicher entfernt?

Diese beiden Fragen scheinen sich auf dasselbe zu beschränken. Dies ist jedoch implementierungsspezifisch und hängt auch davon ab, ob der Status auf dem Server oder dem Client gespeichert ist. Eine etwas anständige Implementierung entfernt es, wenn es abgelaufen ist oder wenn die Warteschlange voll ist. Mojarra hat beispielsweise ein Standardlimit von 15 logischen Ansichten, wenn das Speichern des Status auf Sitzung eingestellt ist. Dies kann mit dem folgenden Kontextparameter konfiguriert werden web.xml:

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

Siehe auch Mojarra-FAQ für andere Mojarra-spezifische Parameter und diese verwandte Antwort com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews


Wenn sich ein angemeldeter Benutzer in der Anwendung durch Seiten navigiert, wird sich der Status der Komponenten weiterhin auf dem Server ansammeln?

Technisch hängt das von der Implementierung ab. Wenn Sie über die Navigation von Seite zu Seite sprechen (nur GET-Anfragen), speichert Mojarra in der Sitzung nichts. Wenn es sich jedoch um POST-Anforderungen handelt (Formulare mit Befehlslinks / Schaltflächen), speichert Mojarra den Status jedes Formulars in der Sitzung bis zur Höchstgrenze. Auf diese Weise kann der Endbenutzer in derselben Sitzung mehrere Formulare in verschiedenen Browser-Registerkarten öffnen.

Wenn die Statusspeicherung auf Client festgelegt ist, speichert JSF nichts in der Sitzung. Sie können dies mit dem folgenden Kontextparameter tun web.xml:

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

Es wird dann in eine verschlüsselte Zeichenfolge in einem versteckten Eingabefeld mit dem Namen javax.faces.ViewStatedes Formulars serialisiert .


Ich verstehe nicht, welchen Vorteil es hat, den Status der UI-Komponente auf der Serverseite beizubehalten. Reicht es nicht aus, die validierten / konvertierten Daten direkt an verwaltete Beans zu übergeben? Kann / sollte ich versuchen, es zu vermeiden?

Dies reicht nicht aus, um die Integrität und Robustheit von JSF sicherzustellen. JSF ist ein dynamisches Framework mit einem einzigen Einstiegspunkt. Ohne staatliches Management, würde man in der Lage Parodie / Hack HTTP - Anfragen in einer bestimmten Art und Weise (zB Manipulieren sein disabled, readonlyund renderedAttribute), läßt JSF tun verschiedene -und möglicherweise hazardful- Dinge. Es wäre sogar anfällig für CSRF-Angriffe und Phishing.


Und wird das nicht zu viel Speicher auf der Serverseite verbrauchen, wenn Tausende von Benutzersitzungen gleichzeitig stattfinden? Ich habe eine Anwendung, in der Benutzer Blogs zu bestimmten Themen veröffentlichen können. Diese Blogs sind ziemlich groß. Wenn ein Postback oder eine Aufforderung zum Anzeigen der Blogs erfolgt, werden die großen Blogs als Teil des Status der Komponenten gespeichert. Dies würde zu viel Speicher verbrauchen. Ist das nicht ein Problem?

Speicher ist besonders billig. Geben Sie dem App-Server einfach genügend Speicher. Wenn die Netzwerkbandbreite für Sie günstiger ist, wechseln Sie einfach zum Speichern des Status auf die Clientseite. Um die beste Übereinstimmung zu finden, testen und profilieren Sie Ihre Webanwendung einfach mit der erwarteten maximalen Anzahl gleichzeitiger Benutzer und geben Sie dem Appserver dann 125% ~ 150% des maximal gemessenen Speichers.

Beachten Sie, dass JSF 2.0 in der Statusverwaltung erheblich verbessert wurde. Es ist möglich, einen Teilzustand zu speichern (z. B. wird nur der Zustand <h:form>anstelle des gesamten Materials von <html>bis zum Ende gespeichert ). Mojarra zum Beispiel macht das. Ein durchschnittliches Formular mit 10 Eingabefeldern (jeweils mit Beschriftung und Nachricht) und 2 Schaltflächen würde nicht mehr als 1 KB benötigen. Bei 15 Ansichten in der Sitzung sollte dies nicht mehr als 15 KB pro Sitzung sein. Bei ~ 1000 gleichzeitigen Benutzersitzungen sollte dies nicht mehr als 15 MB sein.

Ihr Anliegen sollte sich mehr auf die realen Objekte (verwaltete Beans und / oder sogar DB-Entitäten) im Sitzungs- oder Anwendungsbereich konzentrieren. Ich habe viele Codes und Projekte gesehen, die unnötigerweise die gesamte Datenbanktabelle in Javas Speicher duplizieren, in Anlehnung an eine Bean mit Sitzungsbereich, in der Java anstelle von SQL zum Filtern / Gruppieren / Anordnen der Datensätze verwendet wird. Bei ~ 1000 Datensätzen würde dies leicht über 10 MB pro Benutzersitzung gehen .


1
Können Sie # 2 klarstellen? Warum kann der Komponentenbaum nicht einfach bei jeder Anforderung neu erstellt werden? Welcher Status muss tatsächlich zwischen Anforderungen gespeichert werden und warum? Der einzige Grund, den Komponentenbaum zwischen Anforderungen zu speichern, scheint die Leistung zu sein.
Ryan

Konzentriertere Frage hier: stackoverflow.com/questions/7349174/…
Ryan

Ihre Antwort war mir sehr klar! Die Probleme hinsichtlich der Leistung und Skalierbarkeit von JSF hängen eng mit der Implementierung des Programmierers zusammen! Man muss wissen, wie man die Technologie richtig einsetzt!
Lucas Batistussi

"Geben Sie dem App-Server einfach genügend Speicher." Ähm, ich habe den Eindruck, dass wir hier über Dinge auf Unternehmensebene sprechen, wenn wir über Tausende von gleichzeitigen Benutzersitzungen sprechen. Wenn Sie über Geräte auf Unternehmensebene in einem Unternehmen verfügen, können Sie dem App-Server nicht einfach "genügend Speicherplatz zur Verfügung stellen", wie dies in Ihrer Linux-Box zu Hause möglich ist.
stu

Ihre Antwort war sehr klar und danke dafür. Warum wurde der JSF-Flash-Bereich ausgeblendet, wenn javax.faces.PARTIAL_STATE_SAVING auf true gesetzt wurde? getFacesContext (). getExternalContext (). getFlash (). put ("buildingId", buildingId).
Mai Thet
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.