2008-09-26 17 views
10

Gibt es eine Möglichkeit, einen HTML-Link mit h: outputLink, einem anderen JSF-Tag oder -Code zu erstellen, um eine Anfrage ohne Gesichter (HTTP GET) mit Anfrageparametern zu erstellen?Wie erstelle ich eine GET-Anfrage mit Parametern unter Verwendung von JSF und Navigationsregeln?

Zum Beispiel habe ich folgende Navigations-Regel

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

In meiner Seite würde ich die folgende HTML-Code ausgeben mag:

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

Ich konnte nur den HTML-Code in die Seite schreiben , aber ich möchte die Navigationsregel verwenden, damit alle URLs in einer einzigen konfigurierbaren Datei definiert werden.

Antwort

11

Dies ist eine interessante Idee. Ich wäre neugierig zu wissen, wie es in der Praxis ausgeht.

Getting die Navigationsregeln

Navigation durch die NavigationHandler behandelt wird. Das Erlangen des NavigationHandlers ist nicht schwierig, aber die API legt die Regeln, die sie benutzt, nicht offen.

Wie ich es sehe, können Sie:

  1. Parse-Gesichter-config.xml auf Initialisierung und speichern Sie die Regeln im Anwendungskontext (leicht)
  2. implementieren Ihre eigenen NavigationHandler, Das ignoriert die Regeln in faces-config.xml oder ergänzt sie mit eigenen Regeln Datei und setzt seine ruleset irgendwie (bearbeitbar, aber braucht ein wenig Arbeit)
  3. Mock Ihre eigenen FacesContext und an die bestehenden Navigations Handler übergeben (wirklich schwierig, zwei Faces Objekt koexistieren in demselben Thread zu machen und äußerst ineffizient)

Nun, Sie ein anderes Problem zu haben. Wo wirst du die Mappings behalten, um die Ansichten nachzuschauen? Hard-Code sie in den Bohnen?

mit den Navigationsregeln

Aus der Hand, kann ich mich zwei Möglichkeiten, wie Sie Parameter enthaltende URLs aus dem Back-End konstruieren könnten. Beide beinhalten die Definition einer Bohne irgendeiner Art.

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

Quelle:

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

Für eine GET-Anfrage können Sie die UIParameters verwenden, um die Werte zu setzen und lassen Sie den Renderer die Parameterliste erstellen.

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

POST

Wenn Sie die URL zu einer Ansicht während einer POST-Aktion festlegen möchten, können Sie es tun, eine Umleitung in einer Aktion mit (aufgerufen durch einen Knopf oder command).

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

Hinweise

Beachten Sie, dass ExternalContext.encodeActionURL verwendet wird, um die Zeichenfolge zu kodieren. Dies ist eine gute Methode, um Code zu erstellen, der über Kontexte hinweg portierbar ist (Portlets usw.). Sie würden encodeResourceURL verwenden, wenn Sie einen Link zu einem Bild oder einer Download-Datei codieren würden.

+2

Beachten Sie, dass ich diese Antwort geschrieben habe, bevor JSF2/JEE6 herauskam. JSF2 fügt Unterstützung für Ansichtsparameter hinzu. Jeder, der auf JSF1.2/JEE5 festsitzt, sollte Seam verwenden. – McDowell

0

Haben Sie ein Formular in Betracht gezogen?

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

ich habe;), aber wie soll ich gonna die Anfrage paramters an die Query-String anhängen? –

+0

Ich weiß nicht über JSF , aber das ist automatisch mit einem HTML

. –

0

Sie könnten einen Befehls-Link mit verschachtelten Param-Tags verwenden. Dies ist im Grunde die gleiche wie hubbardr oben gesagt:

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

Dann in Ihrem Backing Bean Sie tun müssen:

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

Und dann tun, was Sie tun müssen.