2008-09-26 8 views
10

Existe-t-il un moyen de créer un lien html en utilisant h: outputLink, une autre balise JSF ou un code pour créer une requête non-face (HTTP GET) avec des paramètres de requête?Comment créer une requête GET avec des paramètres, en utilisant JSF et les règles de navigation?

Par exemple je la navigation règle

<navigation-rule> 
    <navigation-case> 
     <from-outcome>showMessage</from-outcome> 
     <to-view-id>/showMessage.jsf</to-view-id> 
     <redirect/> 
    </navigation-case> 
</navigation-rule> 

suivant Dans ma page, je voudrais sortir le code html suivant:

<a href="/showMessage.jsf?msg=23">click to see the message</a> 

je pouvais écrire le code html dans la page , mais je souhaite utiliser la règle de navigation pour que toutes les URL soient définies dans un seul fichier configurable.

Répondre

11

Ceci est une idée intéressante. Je serais curieux de savoir comment ça se passe en pratique.

Obtenir les règles de navigation

Navigation est assurée par le NavigationHandler. Obtenir le gestionnaire de navigation n'est pas difficile, mais l'API n'expose pas les règles qu'elle utilise.

Comme je le vois, vous pouvez:

  1. Parse faces-config.xml lors de l'initialisation et de stocker les règles dans le contexte d'application (facile)
  2. mettre en œuvre votre propre NavigationHandler qui ne tient pas compte des règles dans faces-config.xml ou les complète avec votre propre fichier de règles et expose son ensemble de règles en quelque sorte (réalisable, mais prend un peu de travail)
  3. mock votre propre FacesContext et passez-le au gestionnaire de navigation existant (vraiment difficile de faire l'objet de deux coexistent dans FacesContext même thread et extrêmement inefficace)

Maintenant, vous avez un autre problème aussi. Où allez-vous garder les cartographies pour rechercher les vues? Hard-code les dans les haricots?

En utilisant les règles de navigation

Off main, je peux penser à deux façons dont vous pouvez construire des URL contenant des paramètres de l'arrière-plan. Les deux impliquent la définition d'un haricot quelconque.

<managed-bean> 
    <managed-bean-name>navBean</managed-bean-name> 
    <managed-bean-class>foo.NavBean</managed-bean-class> 
    <managed-bean-scope>application</managed-bean-scope> 
</managed-bean> 

Source:

package foo; 

import java.io.IOException; 
import java.io.Serializable; 
import java.net.URLEncoder; 

import javax.faces.context.ExternalContext; 
import javax.faces.context.FacesContext; 

public class NavBean implements Serializable { 

    private String getView() { 
     String viewId = "/showMessage.faces"; // or look this up somewhere 
     return viewId; 
    } 

    /** 
    * Regular link to page 
    */ 
    public String getUrlLink() { 
     FacesContext context = FacesContext.getCurrentInstance(); 
     ExternalContext extContext = context.getExternalContext(); 
     String viewId = getView(); 
     String navUrl = context.getExternalContext().encodeActionURL(
       extContext.getRequestContextPath() + viewId); 
     return navUrl; 
    } 

    /** 
    * Just some value 
    */ 
    public String getValue() { 
     return "" + System.currentTimeMillis(); 
    } 

    /** 
    * Invoked by action 
    */ 
    public String invokeRedirect() { 
     FacesContext context = FacesContext.getCurrentInstance(); 
     ExternalContext extContext = context.getExternalContext(); 
     String viewId = getView(); 
     try { 
      String charEncoding = extContext.getRequestCharacterEncoding(); 
      String name = URLEncoder.encode("foo", charEncoding); 
      String value = URLEncoder.encode(getValue(), charEncoding); 
      viewId = extContext.getRequestContextPath() + viewId + '?' + name 
        + "=" + value; 
      String urlLink = context.getExternalContext().encodeActionURL(
        viewId); 
      extContext.redirect(urlLink); 
     } catch (IOException e) { 
      extContext.log(getClass().getName() + ".invokeRedirect", e); 
     } 
     return null; 
    } 

} 

GET

Pour une requête GET, vous pouvez utiliser les UIParameters pour définir les valeurs et laisser le moteur de rendu construire la liste des paramètres.

<h:outputLink value="#{navBean.urlLink}"> 
    <f:param name="foo" value="#{navBean.value}" /> 
    <h:outputText value="get" /> 
</h:outputLink> 

POST

Si vous souhaitez définir l'URL à vue au cours d'une action POST, vous pouvez le faire en utilisant une redirection dans une action (appelée par un bouton ou commandLink).

<h:commandLink id="myCommandLink" action="#{navBean.invokeRedirect}"> 
    <h:outputText value="post" /> 
</h:commandLink> 

Remarques

Notez que ExternalContext.encodeActionURL est utilisé pour coder la chaîne. C'est une bonne pratique pour produire du code portable dans tous les contextes (portlets, etcetera). Vous utiliseriez encodeResourceURL si vous étiez en train d'encoder un lien vers une image ou un fichier de téléchargement.

+2

Notez que j'ai écrit cette réponse avant la sortie de JSF2/JEE6. JSF2 ajoute le support pour les paramètres d'affichage. Toute personne bloquée sur JSF1.2/JEE5 devrait envisager d'utiliser Seam. – McDowell

0

Avez-vous regardé un formulaire?

<h:form> 
    <h:commandLink value="Click to see the message" action="#{handler.outcome}" /> 
    <h:inputHidden id="msgId" value="#{bean.msgId}"/> 
</h:form> 
+0

J'ai;) mais comment vais-je ajouter les paramters demande à la chaîne de requête? –

+0

Je ne connais pas JSF , mais ceci est automatique avec un HTML

. –

0

Vous pouvez utiliser un commandLink avec des balises param imbriquées. Ceci est essentiellement le même que hubbardr dit plus haut:

<h:form> 
    <h:commandLink value="click here" action="${handler.outcome}"> 
    <f:param name="msgId" value="${bean.id}" /> 
    </h:commandLink> 
</h:form> 

Ensuite, dans votre backing bean que vous devez faire:

Map requestMap = FacesContext.getCurrentInstance() 
       .getExternalContext().getRequestParameterMap(); 
String msgId = (String) requestMap.get("msgId"); 

Et puis faire tout ce que vous devez faire.

Questions connexes