有没有办法使用 h:outputLink、其他 JSF 标记或代码创建带有请求参数的非面部请求 (HTTP GET) 的 html 链接?
例如我有以下导航规则
<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。
最佳答案
这是一个有趣的想法。我很想知道它在实践中的效果如何。
获取导航规则
导航由 NavigationHandler 处理.掌握 NavigationHandler 并不困难,但 API 不会公开它使用的规则。
在我看来,您可以:
- 在初始化时解析 faces-config.xml 并将规则存储在应用程序上下文中(简单)
- 实现您自己的 NavigationHandler,忽略 faces-config.xml 中的规则或使用您自己的规则文件补充它们并以某种方式公开其规则集(可行,但需要一些工作)
- 模拟你自己的 FacesContext并将其传递给现有的导航处理程序(很难让两个 FacesContext 对象共存于同一个线程中并且效率极低)
现在,您还有另一个问题。您打算在哪里保存映射以查找 View ?将它们硬编码到 bean 中?
使用导航规则
另一方面,我可以想到两种从后端构建包含参数的 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 请求,您可以使用 UIParameters 设置值并让渲染器构建参数列表。
<h:outputLink value="#{navBean.urlLink}">
<f:param name="foo" value="#{navBean.value}" />
<h:outputText value="get" />
</h:outputLink>
发布
如果您想在 POST 操作期间将 URL 设置为 View ,您可以在操作中使用重定向(通过按钮或 commandLink 调用)。
<h:commandLink id="myCommandLink" action="#{navBean.invokeRedirect}">
<h:outputText value="post" />
</h:commandLink>
注意事项
请注意 ExternalContext.encodeActionURL用于对字符串进行编码。这是生成可跨上下文(portlet 等)移植的代码的良好实践。如果您要对指向图像或下载文件的链接进行编码,则可以使用 encodeResourceURL。
关于java - 如何使用 JSF 和导航规则创建带参数的 GET 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/138617/