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

Han*_*sky 146 jsf jsf-2 viewparams viewaction

任何人都可以澄清我们如何在一般情况下使用,或者在现实世界中使用这个代码片段?

<f:metadata>
    <f:viewParam id="id" value="#{bean.id}" />
    <f:viewAction action="#{bean.init}" />
</f:metadata>
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 285

处理GET参数

<f:viewParam>管理的GET参数的设置,转换和验证.这就像<h:inputText>,但GET参数.

以下示例

<f:metadata>
    <f:viewParam name="id" value="#{bean.id}" />
</f:metadata>
Run Code Online (Sandbox Code Playgroud)

基本上做了以下几点:

  • 按名称获取请求参数值id.
  • 如有必要,转换并验证它(您可以使用required,validator并使用converter属性和嵌套a <f:converter><f:validator>in <h:inputText>)
  • 如果转换和验证成功,则将其设置为由#{bean.id}value 表示的bean属性,或者如果该value属性不存在,则将其设置为name ontribtue on name,id以便#{id}在视图中可用.

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

至于验证,以下示例将param设置为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" />
Run Code Online (Sandbox Code Playgroud)

对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" />
Run Code Online (Sandbox Code Playgroud)

public void onload() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

<f:viewAction>然而,自从JSF 2.2(<f:viewParam>自JSF 2.0以来已经存在)以来,这是新的.如果您无法升级,那么您最好的选择是使用<f:event>.

<f:event type="preRenderView" listener="#{bean.onload}" />
Run Code Online (Sandbox Code Playgroud)

但是,每次请求都会调用它.您需要明确检查请求是否不是回发:

public void onload() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想跳过"转换/验证失败"的情况,请执行以下操作:

public void onload() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    if (!facesContext.isPostback() && !facesContext.isValidationFailed()) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

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


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

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

<h:link outcome="next" includeViewParams="true">
<!-- Or -->
<h:link outcome="next?includeViewParams=true">
Run Code Online (Sandbox Code Playgroud)

用上面的<f:metadata>例子生成的基本上是以下链接

<a href="next.xhtml?id=10">
Run Code Online (Sandbox Code Playgroud)

使用原始参数值.

这种方法只需要的是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>
Run Code Online (Sandbox Code Playgroud)

基本上这个@RequestScopedbean:

private String query;
private List<Result> results;

public void search() {
    results = service.search(query);
}
Run Code Online (Sandbox Code Playgroud)

需要注意的是,<h:message>对于<f:viewParam>,而不是普通的HTML <input type="text">!还要注意的是,输入值显示#{param.query}#{bean.query}是空的,因为提交的值,否则不会显示在所有的时候有一个验证或转换错误.请注意,这个结构对于JSF输入组件是无效的(它已经在"掩盖"之下).


也可以看看: