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

6

f:param可以很好地与h:link一起使用,但无法与p:commandLinkh:commandLink一起使用。

例如,我有两个页面test_first.xhtmltest_second.xhtml,以及一个后台java beanTestBean.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;
    }
}

相关链接:https://dev59.com/om855IYBdhLWcg3weUQQ#4317723 - BalusC
2个回答

8
您误解了两个标记的含义,即<h:link><h:commandLink>,因此,您也误解了附加到这两个标记之一的<f:param>的含义。无论如何,在提问之前阅读文档以获得更深入的见解是值得的。

<h:link> renders an HTML "a" anchor element. The value of the component is rendered as the anchor text and the outcome of the component is used to determine the target URL rendered in the "href" attribute. Any child UIParameter components are appended to the String to be output as the value of the "href" attribute as query parameters before rendering...

<h:commandLink> render an HTML "a" anchor element that acts like a form submit button* when clicked ... if the disabled attribute is not present, or its value is false. It renders "#" as the value of the "href" attribute, renders the current value of the component as the link text if it is specified and *renders JavaScript that is functionally equivalent to the following as the value of the "onclick" attribute:

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()" 

where hiddenFieldName is as described above, CLIENT_ID is the clientId of the UICommand component, PARAM_NAME and PARAM_VALUE are the names and values, respectively, of any nested UIParameter children.

换句话说,在<h:link>标记中嵌套的<f:param>将成为生成的URL的查询参数,而在<h:commandLink>标记中嵌套的<f:param>将成为带有给定值的请求参数。
第一个选项很清楚,第二个选项值得更好的解释。要理解它的作用,请考虑如果我们从细节中抽象出来,<h:commandLink>会发送一个POST请求,并将所有嵌套的<f:param>标记附加为请求参数。但如何处理这些参数取决于您,因为导航完全由您控制。
因此,第一种选择是设置硬编码的action属性,其使用情况令人怀疑,例如action="second-page",以这种方式您根本没有传递任何查询参数。所做的是将其提交到相同的视图并在不执行任何操作的情况下转发到第二个页面。非常愚蠢的操作。
第二个选项是指定操作方法,例如action="#{bean.action}"。在这种情况下,您必须在提供的操作方法中处理导航,即从方法返回null/void进行回传,或者返回导航情况结果作为字符串以前往指定视图。至于使用<f:param>传递的请求参数,它们将使用标准JSF方法可用,例如在请求范围的bean上调用@ManagedProperty(“#{param.name}”),或通过在任何范围的bean中调用ExternalContext#getRequestParameterMap(),例如在操作方法中,例如String param = externalContext.getRequestParameterMap().get("name") 。因此,现在您已经在操作方法中拥有了您可以自由使用的参数,只需遵守现有的URL规则即可。
还有两件值得一提的事情。请记住,通过调用命令链接传递的请求参数仅在同一请求中可用,因为您可能希望它能够生存faces-redirect=true,这基本上会触发另一个请求。另一个选项是指定includeviewparams=true以传递当前视图的参数,如果需要的话,如其他答案所述。

2

你可以通过在 action 属性上直接使用 & 连接参数来完成它:

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

更新1

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接