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

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

最佳答案

处理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的请求属性,以便 View 中的#{id}可用。

  • 因此,当您以foo.xhtml?id=10的形式打开页面时,就在呈现 View 之前,以这种方式在Bean中设置了参数值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起是新的(自JSF 2.0起<f:viewParam>已经存在)。如果您无法升级,那么最好的选择是使用 <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>的原因。

    将 View 参数传递给下一个 View
    您可以通过将includeViewParams属性设置为true或通过添加includeViewParams=true请求参数来“传递”导航链接中的 View 参数。
    <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>
    
    基本上,这个@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输入组件无效(它已经在“幕后”进行了操作)。

    也可以看看:
  • ViewParam vs @ManagedProperty(value = "#{param.id}")
  • Communication in JSF 2.0 - Processing GET request parameters
  • 09-16 11:45