有没有办法使用h:outputLink,其他JSF标签或代码创建一个html链接来创建一个具有请求参数的非面部请求(HTTP GET)?
例如我有以下导航规则
- <navigation-rule>
- <navigation-case>
- <from-outcome>showMessage</from-outcome>
- <to-view-id>/showMessage.jsf</to-view-id>
- <redirect/>
- </navigation-case>
- </navigation-rule>
- <a href="/showMessage.jsf?msg=23">click to see the message</a>
@R_502_323@
这是一个有趣的想法.我很想知道在实践中如何平静下来.
获取导航规则
导航由NavigationHandler处理.保持NavigationHandler并不困难,但是API并没有公开其使用的规则.
我看到,你可以:
>在初始化时解析faces-config.xml并将规则存储在应用程序上下文中(容易)
>实现自己的NavigationHandler,忽略faces-config.xml中的规则,或者用自己的规则文件来补充它们,并以某种方式公开其规则集(可行,但需要一些工作)
>模拟自己的FacesContext并将其传递给现有的导航处理程序(真的很难使两个FacesContext对象在同一个线程中共存并且非常低效)
现在,你也有另一个问题.你要在哪里保持映射查看视图?在豆中硬编码?
使用导航规则
不过,我可以想到两种可以从后端构建参数的URL.两者都涉及定义某种豆类.
- <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
如果要在POST操作期间将URL设置为视图,则可以使用操作中的重定向(由按钮或commandLink调用)来实现.
- <h:commandLink id="myCommandLink" action="#{navBean.invokeRedirect}">
- <h:outputText value="post" />
- </h:commandLink>
笔记
请注意,ExternalContext.encodeActionURL用于对字符串进行编码.这是生成可以跨上下文(portlet等)移植的代码的好习惯.如果要编码图像或下载文件的链接,则可以使用encodeResourceURL.