<f:metadata>,<f:viewParam>和<f:viewAction>可以用来做什么?


149

任何人都可以阐明我们如何在一般片段或实际示例中使用此片段吗?

<f:metadata>
    <f:viewParam id="id" value="#{bean.id}" />
    <f:viewAction action="#{bean.init}" />
</f:metadata>

Answers:


288

处理GET参数

<f:viewParam>管理的GET参数的设置,转换和验证。就像一样<h:inputText>,然后是GET参数。

下面的例子

<f:metadata>
    <f:viewParam name="id" value="#{bean.id}" />
</f:metadata>

基本上执行以下操作:

  • 按名称获取请求参数值id
  • 转换并在必要时对其进行验证(你可以使用requiredvalidator并且converter属性和巢<f:converter>,并<f:validator>在它像如<h:inputText>
  • 如果转换和验证成功,则将其设置为由#{bean.id}value 表示的Bean属性,或者如果该value属性不存在,则将其设置为名称的请求属性,id以便#{id}在视图中可用。

因此,当您打开页面时,就在呈现视图之前,以这种方式在Bean中设置foo.xhtml?id=10了参数值10

关于验证,以下示例将参数设置为,required="true"并且仅允许10到20之间的值。任何验证失败将导致显示消息。

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
</f:metadata>
<h:message for="id" />

对GET参数执行业务操作

您可以<f:viewAction>为此使用。

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
    <f:viewAction action="#{bean.onload}" />
</f:metadata>
<h:message for="id" />

public void onload() {
    // ...
}

<f:viewAction>但是,这是自JSF 2.2以来的新功能(<f:viewParam>自JSF 2.0起已经存在)。如果您无法升级,那么最好的选择就是使用它<f:event>

<f:event type="preRenderView" listener="#{bean.onload}" />

但是,将在每个请求上调用它。您需要明确检查请求是否不是回发:

public void onload() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}

当您也想跳过“转换/验证失败”的情况时,请执行以下操作:

public void onload() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    if (!facesContext.isPostback() && !facesContext.isValidationFailed()) {
        // ...
    }
}

<f:event>本质上,使用这种方法是一种解决方法/黑客,这就是<f:viewAction>JSF 2.2中引入的原因。


将视图参数传递给下一个视图

您可以通过将includeViewParams属性设置为true或添加includeViewParams=true请求参数来“传递”导航链接中的视图参数。

<h:link outcome="next" includeViewParams="true">
<!-- Or -->
<h:link outcome="next?includeViewParams=true">

上面的<f:metadata>示例基本上生成了以下链接

<a href="next.xhtml?id=10">

使用原始参数值。

这种方法只需要的是next.xhtml也是<f:viewParam>对非常相同的参数,否则它不会被通过。


在JSF中使用GET表单

<f:viewParam>也可以结合使用“纯HTML” GET形式。

<f:metadata>
    <f:viewParam id="query" name="query" value="#{bean.query}" />
    <f:viewAction action="#{bean.search}" />
</f:metadata>
...
<form>
    <label for="query">Query</label>
    <input type="text" name="query" value="#{empty bean.query ? param.query : bean.query}" />
    <input type="submit" value="Search" />
    <h:message for="query" />
</form>
...
<h:dataTable value="#{bean.results}" var="result" rendered="#{not empty bean.results}">
     ...
</h:dataTable>

基本上有了这个@RequestScopedbean:

private String query;
private List<Result> results;

public void search() {
    results = service.search(query);
}

请注意,<h:message>是用于<f:viewParam>,而不是纯HTML <input type="text">!还要注意的是,输入值显示#{param.query}#{bean.query}是空的,因为提交的值,否则不会在所有显示出来时,有一个验证或转换错误。请注意,此构造对于JSF输入组件无效(它已经在“幕后”进行了操作)。


也可以看看:


@BalusC与faces-redirect = true结合使用时,“ bean”的范围应该是什么?如果将范围设置为“ @RequestScoped”,它将按预期工作吗?
极客

@Geek:重定向创建一个新的GET请求。源bean和目标bean的bean范围无关。但是,对于请求,您应该考虑新GET请求的可能影响,并查看作用域Bean。另请参见stackoverflow.com/questions/7031885/...
BalusC

@BalusC的确切含义是:“但是,对于请求并查看作用域的bean,您应该考虑新的GET请求的可能含义。”
极客

@Geek:它们将被废弃并重新创建,因为它们的作用域将随后终止并开始。
BalusC 2012年

@BalusC。全面的答案。“当您需要使用'@'PostConstruct之类的功能来查看不是在每个请求上都调用的视图范围bean时,请检查该请求是否不是回发”。如果不是在每个请求上都调用它,那么为什么要检查该请求是否为回发?
Uluk Biy 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.