web-dev-qa-db-fra.com

Pourquoi JSF enregistre-t-il l'état des composants de l'interface utilisateur sur le serveur?

  1. Jusqu'à quel moment JSF enregistre-t-il l'état des composants de l'interface utilisateur côté serveur et quand exactement l'information sur l'état du composant de l'interface utilisateur est-elle supprimée de la mémoire du serveur? Lorsqu'un utilisateur connecté à l'application navigue dans des pages, l'état des composants continuera-t-il à s'accumuler sur le serveur?

  2. Je ne comprends pas quel est l'avantage de conserver l'état des composants de l'interface utilisateur sur le serveur!? La transmission directe des données validées/converties aux beans gérés n'est-elle pas suffisante? ? Puis-je ou devrais-je essayer de l'éviter?

  3. Est-ce que cela ne consomme pas trop du côté serveur, s'il y a des milliers de sessions utilisateur simultanées? J'ai une application où les utilisateurs peuvent poster des blogs sur certains sujets. Ces blogs sont assez grands. Lorsqu’il y aura un post-retour ou une demande d’affichage des blogs, les données de cette grande page seront-elles sauvegardées en tant que partie de l’état des composants? trop de mémoire. N'est-ce pas une préoccupation?


Mise à jour 1:

Désormais, il n'est plus nécessaire de sauvegarder l'état lors de l'utilisation de JSF. Une implémentation JSF sans état hautes performances est disponible. Voir ceci blog & cette question pour les détails pertinents et la discussion. En outre, il existe un problème issue à inclure dans les spécifications JSF, une option permettant de fournir le mode sans état à JSF. (P.S. Envisagez de voter pour les problèmes this & this si cela vous est utile.)


Mise à jour 2 (24-02-2013):

Une bonne nouvelle que Mojarra 2.1.19 est sorti avec le mode sans état !

Vois ici:

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

103
Rajat Gupta

Pourquoi JSF doit-il sauvegarder l'état des composants de l'interface utilisateur côté serveur?

Parce que HTTP est sans état et JSF est avec état. L'arborescence des composants JSF est soumise à des modifications dynamiques (par programmation). JSF a simplement besoin de connaître l'état exact tel qu'il était lorsque le formulaire a été affiché pour l'utilisateur final, afin de pouvoir traiter avec succès le cycle de vie complet du fichier JSF en fonction des informations fournies par l'arborescence des composants JSF d'origine lorsque le formulaire a été soumis à nouveau. le serveur. L'arborescence des composants fournit des informations sur les noms de paramètre de requête, les convertisseurs/validateurs nécessaires, les propriétés de bean géré liées et les méthodes d'action.


Jusqu'à quel moment JSF enregistre-t-il l'état des composants de l'interface utilisateur côté serveur et à quel moment exactement les informations d'état des composants de l'interface utilisateur sont-elles supprimées de la mémoire du serveur?

Ces deux questions semblent se résumer au même. Quoi qu'il en soit, cela dépend de l'implémentation et dépend également du fait que l'état est enregistré sur le serveur ou sur le client. Une implémentation un peu décente l’enlèvera à l’expiration de son délai ou lorsque la file est pleine. Mojarra, par exemple, a une limite par défaut de 15 vues logiques lorsque l'enregistrement d'état est défini sur session. Ceci est configurable avec le paramètre de contexte suivant dans web.xml:

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

Voir aussi FAQ de Mojarra pour d'autres paramètres spécifiques à Mojarra et cette réponse associée com.Sun.faces.numberOfViewsInSession vs com.Sun.faces.numberOfLogicalViews


Lorsqu'un utilisateur connecté à l'application navigue dans des pages, l'état des composants continuera-t-il à s'accumuler sur le serveur?

Techniquement, cela dépend de la mise en œuvre. Si vous parlez de navigation de page à page (uniquement des requêtes GET), Mojarra n'enregistrera rien en session. S'ils sont cependant POST demandes (formulaires avec liens de commande/boutons), Mojarra enregistrera l'état de chaque formulaire dans la session jusqu'à la limite maximale. Cela permettra à l'utilisateur d'ouvrir plusieurs formulaires dans différents onglets de navigateur. dans la même session.

Ou, lorsque l'enregistrement d'état est défini sur client, JSF ne stocke rien dans la session. Vous pouvez le faire avec le paramètre de contexte suivant dans web.xml:

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

Il sera ensuite sérialisé en chaîne cryptée dans un champ de saisie masqué portant le nom javax.faces.ViewState de la forme.


Je ne comprends pas quel est l'avantage de conserver l'état du composant d'interface utilisateur côté serveur. La transmission directe des données validées/converties aux beans gérés ne suffit-elle pas? Puis-je/devrais-je essayer de l'éviter?

Ce n'est pas suffisant pour assurer l'intégrité et la robustesse de JSF. JSF est un cadre dynamique avec un seul point de contrôle. Sans une gestion d'état, on pourrait usurper les requêtes HTTP d'une certaine manière (par exemple, en manipulant les attributs disabled, readonly et rendered), pour laisser JSF faire des choses différentes - et des choses potentiellement dangereuses. Il serait même sujet aux attaques CSRF et au phishing.


Et cela ne consommera-t-il pas trop de mémoire côté serveur, s'il y a des milliers de sessions utilisateur simultanées? J'ai une application où les utilisateurs peuvent poster des blogs sur certains sujets. Ces blogs sont assez grands. Lorsqu’il y aura un post-retour ou une demande d’affichage des blogs, les gros blogs seront sauvegardés en tant que partie de l’état des composants. Cela consommerait trop de mémoire. N'est-ce pas une préoccupation?

La mémoire est particulièrement bon marché. Il suffit de laisser suffisamment de mémoire au serveur d'applications. Ou, si la bande passante réseau vous coûte moins cher, il suffit de basculer les économies d’état sur le côté client. Pour trouver la meilleure correspondance, il suffit de stresstest et de profiler votre application Web avec le nombre maximum d'utilisateurs simultanés attendus, puis de donner au serveur d'applications 125% à 150% de la mémoire maximale mesurée.

Notez que JSF 2.0 a beaucoup amélioré la gestion des états. Il est possible de sauvegarder un état partiel (par exemple uniquement le <h:form> sera sauvegardé à la place de tout le contenu de <html> jusqu’à la fin). Mojarra par exemple le fait. Un formulaire moyen avec 10 champs de saisie (chacun avec une étiquette et un message) et 2 boutons ne prendrait pas plus de 1 Ko. Avec 15 vues en session, cela ne devrait pas dépasser 15 Ko par session. Avec environ 1 000 sessions utilisateur simultanées, cela ne devrait pas dépasser 15 Mo.

Votre préoccupation doit être davantage centrée sur les objets réels (beans gérés et/ou même entités de base de données) dans la portée de la session ou de l'application. J'ai vu beaucoup de codes et de projets qui dupliquent inutilement l'intégralité de la table de la base de données dans la mémoire de Java sous la forme d'un bean de portée de session où Java a été utilisé à la place de SQL pour filtrer/grouper/organiser le Avec environ 1 000 enregistrements, cela dépasserait facilement 10 Mo par session utilisateur .

196
BalusC