Domanda

Esiste un modo per creare un collegamento html utilizzando h: outputLink, altri tag o codice JSF per creare una richiesta non volti (HTTP GET) con parametri di richiesta?

Ad esempio ho la seguente regola di navigazione

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

Nella mia pagina vorrei produrre il seguente codice html:

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

Potrei semplicemente scrivere il codice html nella pagina, ma voglio usare la regola di navigazione per avere tutti gli URL definiti in un singolo file configurabile.

È stato utile?

Soluzione

Questa è un'idea interessante. Sarei curioso di sapere come funziona in pratica.

Ottenere le regole di navigazione

La navigazione è gestita da NavigationHandler . Ottenere il NavigationHandler non è difficile, ma l'API non espone le regole che utilizza.

A mio avviso, puoi:

  1. analizza faces-config.xml all'inizializzazione e archivia le regole nel contesto dell'applicazione ( facile )
  2. implementa il tuo NavigationHandler che ignora le regole in faces-config.xml o le integra con il tuo file delle regole ed espone in qualche modo il suo set di regole ( praticabile, ma richiede un po 'di lavoro )
  3. prendi in giro il tuo FacesContext e passalo al gestore di navigazione esistente ( davvero difficile far coesistere due oggetti FacesContext nello stesso thread ed estremamente inefficienti )

Ora hai anche un altro problema. Dove hai intenzione di mantenere le mappature per cercare le viste? Li codifichi nei bean?

Uso delle regole di navigazione

D'altra parte, posso pensare a due modi in cui potresti creare URL contenenti parametri dal back-end. Entrambi implicano la definizione di un fagiolo di qualche tipo.

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

Fonte:

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

}

Per una richiesta GET, è possibile utilizzare gli UIParameters per impostare i valori e consentire al renderer di creare l'elenco dei parametri.

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

POST

Se vuoi impostare l'URL su una vista durante un'azione POST, puoi farlo usando un reindirizzamento in un'azione (invocato da un pulsante o commandLink).

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

Note

Nota che ExternalContext.encodeActionURL viene utilizzato per codificare la stringa. Questa è una buona pratica per la produzione di codice portatile in tutti i contesti (portlet, eccetera). Utilizzeresti encodeResourceURL se stessi codificando un link a un'immagine o scarichi un file.

Altri suggerimenti

Hai provato a utilizzare PrettyFaces? È un'estensione JSF open source progettata specificamente per rendere possibili le pagine JSF / JSF con segnalibri con richieste GET.

PrettyFaces - SEO, Parametri dinamici, Segnalibri e navigazione per JSF / JSF2

Hai preso in considerazione un modulo?

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

Puoi usare un commandLink con tag param nidificati. Questo è fondamentalmente lo stesso di hubbardr detto sopra:

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

Quindi nel backing bean devi fare:

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

E poi fai tutto ciò che devi fare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top