JSF: bean portée; session vs demande
J'ai un managed bean appelé UserSearchHandler
, il a un doSearch
méthode qui remplit UserSearchHandler.searchResults
qui sont affichés dans un tableau sur le userSearch.xhtml
page.
J'ai un autre bean géré appelé UserHandler
, il a un showUser
méthode et ainsi de suite.
Dans le tableau des résultats de recherche, le nom d'utilisateur est un lien qui, lorsqu'il est cliqué, est censé afficher les détails de l'utilisateur sur un userView.xhtml
page. La table et le lien ressemble à ceci:
<p:dataTable var="user" value="#{userSearchHandler.searchResults" >
//... and so on ... then
<h:commandLink value="#{user.firstName}" action="#{userHandler.showUser}">
<f:setPropertyActionListener target="#{userHandler.userIdToShow}" value="#{profile.id}"/>
</h:commandLink>
Tout fonctionne bien lorsque la gestion de haricots sont mis à session
portée.
Cependant, lorsque je change la portée sur les haricots à request
la recherche fonctionne, et le tableau est renseigné, mais quand je clique sur le lien rien ne se passe. J'ai mis un point d'arrêt sur la userHandler.showUser
méthode et elle n'est jamais atteint lorsque le userSearchHandler
est réglé sur "demande" de la portée.
Quelqu'un peut aider à expliquer pourquoi il en est, ou ce que je fais mal?
Vous devez vous connecter pour publier un commentaire.
C'est parce que la
#{userSearchHandler.searchResults}
est vide lors de la nouvelle demande et, par conséquent, JSF est incapable de localiser la ligne concernée où la commandlink est été invoqué dans le but d'invoquer l'action (et de passer/définir les propriétés le cas échéant).Vous devez vous assurer que le même
#{userSearchHandler.searchResults}
est créés au préalable lors de l'haricot de construction/d'initialisation. Si c'est pour être créé sur la base d'un ensemble de paramètres spécifiques, alors vous avez à les transmettre avec le formulaire.C'est exactement la raison pour laquelle les solutions de Tomahawk est
<t:saveState />
et de nouvelles JSF 2.0 portée de vue existent.Voir aussi:
t:saveState
(pas sûr si PrimeFaces offres similaires interne, solution pour ce que, je n'ai jamais utilisé PrimeFaces sur JSF 1.x).<t:saveState value="#{userSearchHandler}" />
à la page. C'est tout. Il se comporte exactement comme la portée de vue (qui aurait travaillé dans votre cas, oui, la soumettre revient à la même vue en tout cas).Serializable
. Si vous ne voulez pas sérialiser un javabean pour quelque raison spécifique (contient des informations sensibles qui vous voudrais de ne pas stocker sur le disque ou le transfert sur le réseau, ou contient des propriétés qui pas être sérialisé, de toute façon commeInputStream
, etc), puis il suffit de les marquertransient
. L'exigence d'être sérialisable par la façon dont s'appliquent également lors de l'utilisation det:saveState
.transient
, il ne sera pas sérialisé et donc aussi de ne pas être disponible après la désérialisation. Si vous l'utilisez correctement, mais leUserService
semble être un javabean ainsi et ainsi, elle a vraiment besoin d'être sérialisable ainsi. C'est juste par contrat.t:saveState
exige également la fève être sérialisable... (voir aussi le commentaire précédent). Si la portée de session ou serialiable est pas vraiment une option, alors vous avez à jouer avec les paramètres de la demande et de la préparation du modèle de données de l'haricot, le constructeur ou l'@PostConstruct
en fonction de ces paramètres.J'ai quelques idées. Si vous êtes en utilisant un à votre navigation, vous pouvez essayer de prendre ça. Le faire signifierait que le navigateur ne sera pas de faire une nouvelle requête HTTP, quand il rend la deuxième fenêtre. C'est la nouvelle requête HTTP qui efface la portée de la requête de haricots. Si ce n'est pas une option, vous pourriez être en mesure de passer un paramètre dans votre lien comme un id d'enregistrement, ce qui pourrait vous permettre d'extraire des données à partir de votre source de données correspondant à l'id.
<redirect/>
, la navigation n'est par défaut pas de feu d'une nouvelle demande. Il utilise justeRequestDispatcher#forward()
sous les couvertures. C'est le formulaire de soumission (un pur interaction avec le client de la pression commandlink/bouton de commande) qui est responsable de la nouvelle demande.