f:param不能与p:commandLink或h:commandLink一起使用查询字符串

时间:2013-08-21 02:39:12

标签: jsf primefaces query-string

f:param适用于h:link,但不适用于p:commandLinkh:commandLink

例如,我有两个页面test_first.xhtmltest_second.xhtml,以及一个支持java bean TestBean.java

我开始运行test_first.xhtml

如果我点击link1 h:link,则该页面将重定向到test_second.xhtml。在f:param的帮助下,浏览器的地址栏将显示.../test_second.xhtml?id=1。在该页面上,testBean.userId被打印出来。

如果我点击link2link3,该网页会重定向到test_second.xhtml。但是,地址栏只显示.../test_second.xhtml,没有?id=#!并且testBean.userId不会打印在该页面上。

如何让commandLinkf:param合作?有时我希望链接不会重定向到另一个页面,而是根据数据调用bean的某些方法。

test_first.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
<h:head/>
<h:body>
<h:form>
    <h:link value="link1" outcome="test_second" >
        <f:param name="id" value="1"/>
    </h:link>
    <br/><br/>
    <h:commandLink value="link2" action="test_second?faces-redirect=true" >
        <f:param name="id" value="2" />
    </h:commandLink>
    <br/><br/>
    <p:commandLink value="link3" action="test_second?faces-redirect=true">
        <f:param name="id" value="3" />
    </p:commandLink>
    <br/><br/>
</h:form>
</h:body>
</html>

test_second.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
<f:metadata>
    <f:viewParam name="id" value="#{testBean.userId}" />
</f:metadata>
<h:head/>
<h:body>
<h:form>
    This is the second page.
    <h:outputText value="Selected id is #{testBean.userId}" />
    <h:commandButton value="Print page id" action="#{testBean.print()}" />
</h:form>
</h:body>
</html>

TestBean.java

@ManagedBean
@SessionScoped
public class TestBean implements Serializable{
    private Integer userId;

    public void print() {
        System.out.println(userId);
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }
}

2 个答案:

答案 0 :(得分:7)

你误解了这两个标签的含义,即<h:link><h:commandLink>,因此,你也误解了附加在两者之一的<f:param>的含义。无论如何,在提出问题以获得更多见解之前,始终阅读文档是值得的。

  

<h:link>呈现HTML“a”锚元素。组件的值呈现为锚文本,组件的结果用于确定在“href”属性中呈现的目标URL。 任何子UIParameter组件都会附加到String中,以便在呈现之前作为查询参数的“href”属性的值输出...

     

<h:commandLink>呈现一个HTML“a”锚元素,当单击时表现为表单提交按钮* ...如果禁用的属性不存在,或者其值为false。它将“#”呈现为“href”属性的值,将组件的当前值呈现为链接文本(如果已指定),并且*将与功能上等效于以下内容的JavaScript呈现为“onclick”属性的值:

document.forms['CLIENT_ID']['hiddenFieldName'].value='CLIENT_ID';    
document.forms['CLIENT_ID']['PARAM1_NAME'].value='PARAM1_VALUE'; 
document.forms['CLIENT_ID']['PARAM2_NAME'].value='PARAM2_VALUE'; return false;
document.forms['CLIENT_ID'].submit()" 
     

其中hiddenFieldName如上所述,CLIENT_ID是UICommand组件的clientId, PARAM _NAME和PARAM _VALUE分别是任何嵌套UIParameter的名称和值儿童

换句话说,在<h:link>标记内,嵌套<f:param>最终将作为生成的网址的查询参数,而在<h:commandLink>标记内,嵌套<f:param>将最终为具有给定值的请求参数。

虽然第一个是明确的,但第二个值得更好地阐述。要了解它的作用,请考虑如果我们从详细信息中抽象出来<h:commandLink>发送POST请求并将所有嵌套的<f:param>标记作为请求参数附加。但是由你来决定如何处理它们,因为导航完全在你手中

所以,第一个选项是设置一个硬编码的action属性,哪个用例可疑,就像action="second-page"一样,你没有' t传递任何查询参数。将要做的是POST到相同的视图并转发到第二个视图而不进行任何操作。相当愚蠢的行动。

第二个选项是指定一个操作方法,例如action="#{bean.action}"。在这种情况下您必须在提供的操作方法中处理导航,即从回发方法返回null / void,或者将导航案例结果作为字符串返回到转发到指定的视图。至于您使用<f:param>传递的请求参数,它们将在请求范围的bean上使用标准JSF意味着,如@ManagedProperty("#{param.name}"),或者通过调用ExternalContext#getRequestParameterMap()在任何作用域中,例如,在动作方法中,如String param = externalContext.getRequestParameterMap().get("name")中所示。现在,您可以使用参数in action方法随意使用自己喜欢的方式,只需遵守一系列适用于URL的规则。

还有两件事值得一提。请记住,通过调用命令链接传递的请求参数将仅在同一请求中可用,因为您可能希望它能够在基本上触发另一个请求的faces-redirect=true中生存。另一个选项是指定includeviewparams=true来传递当前视图的参数,如果需要的话,如另一个答案所述。

答案 1 :(得分:2)

您可以通过直接在action属性中将参数与&连接来实现:

<p:commandLink value="link3" action="test_second?faces-redirect=true&id=3"/>

更新1

您也可以考虑添加&includeViewParams=true。这样,您的目标导航视图参数将自动包含在内。