有没有办法使用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代码,但我想使用导航规则,以便在一个可配置文件中定义所有网址。

有帮助吗?

解决方案

这是一个有趣的想法。我很想知道它在实践中是如何实现的。

获取导航规则

导航由处理NavigationHandler 的。掌握NavigationHandler并不困难,但API不会公开它使用的规则。

在我看来,你可以:

  1. 在初始化时解析faces-config.xml并将规则存储在应用程序上下文中( easy
  2. 实现您自己的NavigationHandler,忽略faces-config.xml中的规则或使用您自己的规则文件对其进行补充,并以某种方式公开其规则集(可行,但需要一些工作
  3. 嘲笑你自己的 FacesContext 并将其传递给现有的导航处理程序(很难使两个FacesContext对象在同一个线程中共存并且效率极低
  4. 现在,你还有另一个问题。你想在哪里保留映射来查看视图?在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设置为视图,可以使用操作中的重定向(由按钮或commandLink调用)来执行此操作。

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

    备注

    请注意 ExternalContext.encodeActionURL 用于对字符串进行编码。这是生成可跨上下文(portlet等)移植的代码的好习惯。如果要编码图像或下载文件的链接,则可以使用 encodeResourceURL

scroll top