D'une action dans mon haricot, j'essaie de rediriger vers une autre page en attente d'un paramètre de vue. Quelle est la manière recommandée de faire cela dans JSF2?
Par exemple, ma page source est la suivante: http: //localhost/page1.xhtml
il a un bouton de commande qui appelle une action:
<h:commandButton value="submit" action="#{myBean.submit}" />
où mon haricot ressemble:
@ManagedBean
@RequestScoped
public class MyBean {
private int id;
public String submit() {
//Does stuff
id = setID();
return "success";
}
Et maintenant, je veux que le retour de l'action 'submit' à naviguer http: //localhost/page2.xhtml? Id = 2
J'ai essayé de faire cela avec un paramètre view-param dans mon cas de navigation, mais avec des résultats étranges. L'extrait de faces-config ressemble à ceci:
<navigation-rule>
<from-view-id>/page1.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/page2.xhtml</to-view-id>
<redirect>
<view-param>
<name>id</name>
<value>#{myBean.id}</value>
</view-param>
</redirect>
</navigation-case>
</navigation-rule>
Le comportement étrange étant que, même si myBean est configuré pour une requête étendue, il appelle uniquement myBean.getId () la première fois que je charge mon application et réutilise la même valeur pour tous les appels suivants, produisant ainsi des paramètres de vue incorrects pour page2.
Donc, je cherche soit un meilleur moyen de le faire, soit une raison/solution pour laquelle le paramètre view-param n'est pas demandé à mon bean à chaque fois.
Le fait de ne pas décider ce qu’il faut envoyer (dans l’action), mais plutôt ce que vous souhaitez recevoir (dans la page cible) n’est pas intuitif lorsque vous passez des paramètres dans JSF.
Lorsque vous effectuez une action qui se termine par une redirection, les métadonnées de la page cible sont chargées et tous les paramètres requis sont lus et ajoutés à l'URL en tant que paramètres.
Notez qu'il s'agit exactement du même mécanisme que pour toute autre liaison JSF: vous ne pouvez pas lire la valeur de inputText à un endroit et le faire écrire ailleurs. L'expression valeur définie dans viewParam est utilisée à la fois pour la lecture (avant la redirection) et pour l'écriture (après la redirection).
Avec votre haricot vous faites juste:
@ManagedBean
@RequestScoped
public class MyBean {
private int id;
public String submit() {
//Does stuff
id = setID();
return "success?faces-redirect=true&includeViewParams=true";
}
// setter and getter for id
Si le receveur a:
<f:metadata>
<f:viewParam name="id" value="#{myBean.id}" />
</f:metadata>
Cela fera exactement ce que vous voulez.
Sans une solution plus agréable, ce que j'ai trouvé efficace, c'est simplement de construire ma chaîne de requête dans la déclaration de bean:
public String submit() {
// Do something
return "/page2.xhtml?faces-redirect=true&id=" + id;
}
Pas la plus flexible des solutions, mais semble fonctionner comme je le veux.
En utilisant également cette approche pour nettoyer le processus de construction de la chaîne de requête: http://www.warski.org/blog/?p=185
Découvrez ces:
Vous allez avoir besoin de quelque chose comme:
<h:link outcome="success">
<f:param name="foo" value="bar"/>
</h:link>
...et...
<f:metadata>
<f:viewParam name="foo" value="#{bean.foo}"/>
</f:metadata>
À en juger par cette page , quelque chose comme cela pourrait être plus facile:
<managed-bean>
<managed-bean-name>blog</managed-bean-name>
<managed-bean-class>com.acme.Blog</managed-bean-class>
<managed-property>
<property-name>entryId</property-name>
<value>#{param['id']}</value>
</managed-property>
</managed-bean>
Vous pouvez le faire en utilisant Primefaces comme ceci:
<p:button
outcome="/page2.xhtml?faces-redirect=true&id=#{myBean.id}">
</p:button>
Ajoutez simplement l'attribut seen pour rediriger la balise comme ci-dessous:
<redirect include-view-params="true">
<view-param>
<name>id</name>
<value>#{myBean.id}</value>
</view-param>
</redirect>
Ici quelques exemples de navigation.