2008-09-26 37 views
10

有沒有辦法使用h:outputLink,其他JSF標籤或代碼創建一個帶請求參數的非面孔請求(HTTP GET)的html鏈接?如何使用JSF和導航規則創建帶有參數的GET請求?

例如我有以下的導航規則

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

在我的網頁我想輸出下面的HTML代碼:

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

我可以只寫html代碼的頁面,但我想要使用導航規則,以便在單個可配置文件中定義所有的URL。

回答

11

這是一個有趣的想法。我很想知道它在實踐中是如何氾濫的。

獲取導航規則

導航由NavigationHandler處理。掌握NavigationHandler並不困難,但API不公開它使用的規則。

在我看來,您可以:

  1. 解析faces-config.xml中的初始化和存儲的規則在應用程序上下文(容易
  2. 實現自己的NavigationHandler忽略的規則faces-config.xml中或將它們用自己的規則文件的補充,並以某種方式暴露了其規則集(可行的,但需要多一點的工作的)
  3. 嘲笑自己FacesContext,並把它傳遞給現有的導航處理器(真的很難作出相同的線程2點FacesContext的對象並存,效率極其低下

現在,你有另外一個問題了。你要在哪裏保持映射來查看視圖?硬編碼他們在豆?

使用的導航規則

副手,我能想到的,你可以構建從後端含參數的URL兩種方式。兩者都涉及定義某種類型的bean。

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

來源:

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

對於GET請求,您可以使用UIParameters設定值,讓渲染器構建參數列表。

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

POST

如果你想設置一個POST操作過程中的URL到視圖,您可以使用一個動作重定向(按一個按鈕或commandLink調用)做到這一點。

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

注意

注意ExternalContext.encodeActionURL用於字符串編碼。這是生成可跨上下文移植的代碼的良好實踐(portlet等)。如果您正在編碼指向圖像或下載文件的鏈接,您將使用encodeResourceURL

0

你考慮過表格嗎?

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

我有;),但我要怎麼請求paramters追加到查詢字符串? – 2008-09-26 14:12:12

+0

我不知道JSF ,但這是自動使用HTML

。 – 2009-11-19 15:58:30

0

你可以使用帶有嵌套參數標籤的commandLink。

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

然後在你的後盾豆你需要做的:

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

然後做你需要做的hubbardr上面說的這是基本相同的。