Comment créer une requête GET avec des paramètres, en utilisant JSF et des règles de navigation?

StackOverflow https://stackoverflow.com/questions/138617

  •  02-07-2019
  •  | 
  •  

Question

Existe-t-il un moyen de créer un lien HTML à l'aide de h: outputLink, d'une autre balise JSF ou d'un code permettant de créer une demande non-faces (HTTP GET) avec des paramètres de demande?

Par exemple, j'ai la règle de navigation suivante

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

Dans ma page, j'aimerais générer le code HTML suivant:

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

Je pourrais simplement é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.

Était-ce utile?

La solution

C'est une idée intéressante. Je serais curieux de savoir comment cela se passe en pratique.

Obtention des règles de navigation

La navigation est gérée par la NavigationHandler . Obtenir le NavigateurHandler n’est pas difficile, mais l’API n’expose pas les règles qu’il utilise.

Comme je le vois, vous pouvez:

  1. analyser le fichier faces-config.xml lors de l'initialisation et stocker les règles dans le contexte de l'application ( easy )
  2. implémentez votre propre NavigationHandler qui ignore les règles de faces-config.xml ou les complète avec votre propre fichier de règles et expose son ensemble de règles ( fonctionne, mais nécessite un peu de travail )
  3. se moque de votre propre FacesContext et transmettez-le au gestionnaire de navigation existant ( il est vraiment difficile de faire coexister deux objets FacesContext dans le même fil et extrêmement inefficace )

Maintenant, vous avez aussi un autre problème. Où allez-vous conserver les mappages pour rechercher les vues? Les coder en dur dans les haricots?

Utilisation des règles de navigation

Je peux imaginer deux manières de construire des URL contenant des paramètres à partir du back-end. Les deux impliquent la définition d'un haricot d'une certaine sorte.

<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;
    }

}

OBTENIR

Pour une requête GET, vous pouvez utiliser les paramètres UIP pour définir les valeurs et laisser le moteur de rendu générer 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 d'une vue lors d'une action POST, vous pouvez le faire en utilisant une redirection dans une action (appelée par un bouton ou un lien de commande).

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

Notes

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, etc.). Vous utiliseriez encodeResourceURL si vous encodiez un lien vers une image ou un fichier téléchargé.

Autres conseils

Essayé d'utiliser PrettyFaces? Il s’agit d’une extension JSF à source ouverte spécialement conçue pour permettre la création de pages JSF / JSF pouvant être mises en signet avec des requêtes GET.

PrettyFaces - SEO, Paramètres dynamiques, Signets et navigation pour JSF / JSF2

Avez-vous envisagé un formulaire?

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

Vous pouvez utiliser un commandLink avec des balises param imbriquées. C'est fondamentalement la même chose que hubbardr a 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 haricot de sauvegarde, vous devez faire:

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

Et ensuite faites ce que vous devez faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top