什么可以<f:metadata>,<f:viewparam>和<f:viewaction>用于?</f:viewaction> </f:viewparam> </f:metadata>

时间:2011-06-16 19:56:21

标签: jsf jsf-2 viewparams viewaction

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

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

2 个答案:

答案 0 :(得分:280)

处理GET参数

<f:viewParam>管理GET参数的设置,转换和验证。它就像<h:inputText>,但接着是GET参数。

以下示例

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

基本上做了以下几点:

  • 按名称id获取请求参数值。
  • 如有必要,转换并验证它(您可以使用requiredvalidatorconverter属性并在其中嵌套<f:converter><f:validator>,就像使用<h:inputText>
  • 如果转换和验证成功,则将其设置为由#{bean.id}值表示的bean属性,或者如果缺少value属性,则将其设置为名称id上的请求属性以便#{id}在视图中提供。

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

关于验证,以下示例将参数设置为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>这种方式实质上是一种解决方法/黑客,这正是JSF 2.2中引入<f:viewAction>的原因。


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

通过将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在同一参数上具有 a <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>

基本上使用这个@RequestScoped bean:

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输入组件是无效的(它已经“在幕后”了)。


另见:

答案 1 :(得分:1)

使用viewParam和includeViewParams = true

将参数从View发送到另一个View,从Sender View发送到Receiver View。

在发件人中

  1. 声明要发送的参数。我们可以发送String,Object,...

Sender.xhtml

<f:metadata>
      <f:viewParam name="ID" value="#{senderMB._strID}" />
</f:metadata>
  1. 我们将发送参数ID,该ID将包含在“includeViewParams=true”中,以作为点击按钮事件的返回字符串 单击按钮使用senderMB._arrData中的dto触发senderMB.clickBtnDetail(dto)

Sender.xhtml

<p:dataTable rowIndexVar="index" id="dataTale"value="#{senderMB._arrData}" var="dto">
      <p:commandButton action="#{senderMB.clickBtnDetail(dto)}" value="見る" 
      ajax="false"/>
</p:dataTable>

在senderMB.clickBtnDetail(dto)中,我们将_strID分配给我们从按钮事件(dto)获得的参数,这里是Sender_DTO并分配给senderMB._strID

Sender_MB.java
    public String clickBtnDetail(sender_DTO sender_dto) {
        this._strID = sender_dto.getStrID();
        return "Receiver?faces-redirect=true&includeViewParams=true";
    }

点击后的链接将变为http://localhost:8080/my_project/view/Receiver.xhtml?*ID=12345*

在接收中

  1. 获取viewParam Receiver.xhtml 在Receiver中,我们声明f:viewParam以从get请求(接收)获取参数,接收方的参数名称必须与发送方(页面)相同

Receiver.xhtml

<f:metadata><f:viewParam name="ID" value="#{receiver_MB._strID}"/></f:metadata>

它将从发送者视图获取参数ID,并将其分配给receive_MB._strID

  1. 使用viewParam 在Receiver中,我们希望在页面渲染之前在sql查询中使用此参数,以便我们使用preRenderView事件。我们将不使用构造函数,因为构造函数将在收到viewParam之前调用 这样我们添加

Receiver.xhtml

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

插入f:metadata标签

Receiver.xhtml

<f:metadata>
<f:viewParam name="ID" value="#{receiver_MB._strID}" />
<f:event listener="#{receiver_MB.preRenderView}"
            type="preRenderView" />
</f:metadata>

现在我们要在读取数据库方法中使用此参数,可以使用

Receiver_MB.java
public void preRenderView(ComponentSystemEvent event) throws Exception {
        if (FacesContext.getCurrentInstance().isPostback()) {
            return;
        }
        readFromDatabase();
    }
private void readFromDatabase() {
//use _strID to read and set property   
}