Pourquoi le JSF sauve-t-il l'état de l'arbre des composants?

il semble y avoir une différence entre l'état géré des haricots et l'état des arbres constitutifs. Vous pouvez contrôler l'état bean géré en utilisant des annotations comme @RequestScoped et @SessionScoped , mais il semble que vous n'avez pas le choix de savoir si l'état de l'arbre des composants est sauvegardé ou non (bien que vous puissiez choisir s'il est sauvegardé sur le serveur ou le client).

il semble que l'état de l'arbre composant devrait être seulement nécessaire pour la durée d'une demande unique en tant que structure de données temporaire pour aider à traiter une demande. Il doit être reconstruit à partir de zéro pour chaque demande. Avec JSF 2.0 la sauvegarde partielle de l'État rend la situation meilleure parce que seules les données de formulaire sont sauvegardées, mais je ne comprends pas pourquoi avoir même les données de formulaire de la demande précédente est utile.

si votre application n'utilise que des fèves gérées en fonction de la portée de la requête, alors il n'est pas logique de sauvegarder l'état de l'arbre des composants entre les requêtes. Même si votre application a session scope managed beans Je supposerais que les beans managed tiendraient l'état et l'arbre des composants n'aurait pas besoin d'avoir un État entre les demandes.

24
demandé sur BalusC 2011-09-08 17:53:33

2 réponses

parce que l'arbre des composants peut être modifié programmatiquement en fonction de la requête initiale. Ceci n'est pas nécessairement reproductible sur la demande ultérieure chaque fois que les données de formulaire doivent être traitées.

plus loin, j'ai l'impression que vous pensez que l'arbre des composants contient aussi les valeurs du modèle. Ce n'est pas vrai. Il ne contient que des références (par langage d'expression) aux valeurs du modèle (les propriétés bean gérées). L'état d'affichage n'est pas copier/dupliquer / contenir l'état du modèle. C'est juste un arbre de composants D'UI. Peut-être que votre confusion est basée sur cela. Il convient de noter que le terme "Données de forme" doit être interprété comme désignant les valeurs soumises et les valeurs du modèle.

voir aussi:

17
répondu BalusC 2017-05-23 12:09:58

ajoute à la réponse précédente, depuis JSF 2.0 quelque chose appelé partial state saving est utilisé par défaut.

le langage de description de vue par défaut dans JSF (Facelets) crée l'arbre des composants entier à partir du Facelet original après chaque requête et initialise les composants à partir de leurs attributs d'étiquette correspondants. Il marque ensuite l'état.

chaque changement d'état subséquent est alors rappelé comme un changement de delta, et c'est cet état qui est effectivement enregistrées. Il pourrait bien s'avérer qu'il n'y a tout simplement pas de tels changements, et alors l'état de la vue est vide (à cause d'un bogue, l'état n'a jamais été vraiment vide, mais cela a été récemment corrigé. Voir http://java.net/jira/browse/JAVASERVERFACES-2203 pour plus de détails)

donc la grande question Est, qu'est-ce qui est réellement dans cet état Alors quand il n'est pas vide?

comme BalusC l'a déjà fait remarquer, cela pourrait le composant de l'arbre. Ces changements peuvent être amorcés à partir de graines de soutien ou à partir de composantes statiques. Un exemple simple du type de composant qui fait ce changement dynamique est un composant de table qui crée des composants de colonne d'enfant basés sur le nombre réel de colonnes dans un ensemble de données.

un autre usage important pour l'état de la vue est de se souvenir des valeurs qui ont été modifiées à l'intérieur des composants, mais qui n'ont pas été insérées dans le modèle. Cela peut être des choses comme feuilleter un interrupteur un interrupteur volet, le déplacement d'un curseur dans un composant dial etc.

un exemple particulier est le composant viewParam , qui se souvient du paramètre request (paramètre query string pour le paramètre GET ou non-faces POST) avec lequel il a été initialisé. Voir ceci pour plus d'informations à ce sujet: http://arjan-tijms.omnifaces.org/2011/07/stateless-vs-stateful-jsf-view.html

il y a aussi une forte relation avec des composants stateful se souvenant de L'état de L'interface utilisateur et de la conversion ou de la validation qui échoue. Dans ce cas, les composants de L'interface se souviendront des valeurs saisies par l'utilisateur et se rappelleront qu'il y a eu une erreur de conversion/validation.

une autre utilisation pour l'état est l'optimisation. Certains composants calculent des valeurs qu'ils jugent coûteuses à calculer et à stocker dans l'état de vue. Par exemple, les composants UIInput font ceci après le premier post-back:

private boolean validateEmptyFields(FacesContext ctx) {

    if (validateEmptyFields == null) {
        ExternalContext extCtx = ctx.getExternalContext();
        String val = extCtx.getInitParameter(VALIDATE_EMPTY_FIELDS_PARAM_NAME);

        if (val == null) {
            val = (String) extCtx.getApplicationMap().get(VALIDATE_EMPTY_FIELDS_PARAM_NAME);
        }
        if (val == null || "auto".equals(val)) {
            validateEmptyFields = isBeansValidationAvailable(ctx);
        } else {
            validateEmptyFields = Boolean.valueOf(val);
        }
    }

    return validateEmptyFields;

}

après ce validateEmptyFields est stocké dans l'état de vue de sorte qu'il ne doit pas être calculé à nouveau sur le formulaire suivant soumet. Une amélioration serait que les utilisateurs puissent choisir entre recalculer ou stocker (l'optimisation bien connue de l'espace-temps).

le concept même de l'état est ce qui a tourmenté le développement d'applications web depuis ses débuts. Tout le monde veut avoir des interactions qui sont essentiellement stateful, mais presque personne ne veut pour le gérer ou même y penser.

JSF a essayé de fournir une réponse ici, mais ce n'est évidemment pas parfait et il ya place à l'amélioration. L'insistance de JSF sur la possibilité de restaurer l'état de la vue (même l'état de la vue vide) peut être gênante, bien que, comme mentionné dans une autre réponse, elle offre une protection implicite contre la CSRF. JSF 2.2 obtiendra une protection CSRF plus explicite (voir par exemple http://arjan-tijms.omnifaces.org/p/jsf-22.html#869 ), nous verrons peut-être des changements à l'avenir.

ayant une option pour désactiver l'état par composant et ayant un crochet facile pour restaurer l'état incase le cadre ne peut pas (comme dans ASP.NET) pourrait également être utile.

21
répondu Arjan Tijms 2017-03-02 09:41:30