問題描述
有沒有辦法使用 h:outputLink、其他 JSF 標記或代碼創建帶有請求參數的非面孔請求 (HTTP GET) 的 html 鏈接?
Is there a way to create an html link using h:outputLink, other JSF tag or code to create a non faces request (HTTP GET) with request parameters?
例如我有以下導航規則
<navigation-rule>
<navigation-case>
<from-outcome>showMessage</from-outcome>
<to-view-id>/showMessage.jsf</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
在我的頁面中,我想輸出以下 html 代碼:
In my page I would like to output the following html code:
<a href="/showMessage.jsf?msg=23">click to see the message</a>
我可以只在頁面中編寫 html 代碼,但我想使用導航規則以便將所有 url 定義在一個可配置文件中.
I could just write the html code in the page, but I want to use the navigation rule in order to have all the urls defined in a single configurable file.
推薦答案
這是一個有趣的想法.我很想知道它在實踐中的表現如何.
This is an interesting idea. I'd be curious to know how it pans out in practice.
獲取導航規則
導航由 處理導航處理程序.掌握 NavigationHandler 并不難,但 API 不會公開它使用的規則.
Navigation is handled by the NavigationHandler. Getting hold of the NavigationHandler isn't difficult, but the API does not expose the rules it uses.
在我看來,你可以:
- 在初始化時解析 faces-config.xml 并將規則存儲在應用程序上下文中 (easy)
- 實現您自己的 NavigationHandler 忽略 faces-config.xml 中的規則或用您自己的規則文件補充它們并以某種方式公開其規則集(可行,但需要一些工作)
- 模擬你自己的 FacesContext 并將其傳遞給現有的導航處理程序(真的很難讓兩個 FacesContext 對象在同一個線程中共存并且效率極低)
- parse faces-config.xml on initialization and store the rules in the application context (easy)
- implement your own NavigationHandler that ignores the rules in faces-config.xml or supplements them with your own rules file and exposes its ruleset somehow (workable, but takes a bit of work)
- mock your own FacesContext and pass it to the existing navigation handler (really difficult to make two FacesContext object coexist in same thread and extremely inefficient)
現在,您還有另一個問題.您要將映射保存在哪里以查找視圖?將它們硬編碼在 bean 中?
Now, you have another problem too. Where are you going to keep the mappings to look up the views? Hard-code them in the beans?
使用導航規則
順便說一句,我可以想到兩種方法可以從后端構造包含參數的 URL.兩者都涉及定義某種 bean.
Off hand, I can think of two ways you could construct parameter-containing URLs from the back-end. Both involve defining a bean of some kind.
<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 請求,您可以使用 UIParameters 設置值并讓渲染器構建參數列表.
For a GET request, you can use the UIParameters to set the values and let the renderer build the parameter list.
<h:outputLink value="#{navBean.urlLink}">
<f:param name="foo" value="#{navBean.value}" />
<h:outputText value="get" />
</h:outputLink>
發布
如果您想在 POST 操作期間將 URL 設置為視圖,您可以在操作中使用重定向(由按鈕或 commandLink 調用).
If you want to set the URL to a view during a POST action, you can do it using a redirect in an action (invoked by a button or commandLink).
<h:commandLink id="myCommandLink" action="#{navBean.invokeRedirect}">
<h:outputText value="post" />
</h:commandLink>
備注
請注意 ExternalContext.encodeActionURL 用于對字符串進行編碼.這是生成可跨上下文(portlet 等)移植的代碼的良好實踐.如果您正在對圖像或下載文件的鏈接進行編碼,則可以使用 encodeResourceURL.
Note that ExternalContext.encodeActionURL is used to encode the string. This is good practice for producing code that is portable across contexts (portlets, etcetera). You would use encodeResourceURL if you were encoding a link to an image or download file.
這篇關于如何使用 JSF 和導航規則創建帶參數的 GET 請求?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!