ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

C
Community

处理 GET 参数

<f:viewParam> 管理 GET 参数的设置、转换和验证。它类似于 <h:inputText>,但用于 GET 参数。

下面的例子

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

基本上执行以下操作:

通过名称id获取请求参数值。

如有必要,对其进行转换和验证(您可以使用 required、validator 和 converter 属性,并在其中嵌套 ,就像使用 一样)

如果转换验证成功,则将其设置为 #{bean.id} 值表示的 bean 属性,或者如果 value 属性不存在,则将其设置为 name 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 以来是新的(自 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> 本质上是一种解决方法/hack,这正是在 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 在相同的参数上有一个 <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">!另请注意,当 #{bean.query} 为空时,输入值会显示 #{param.query},否则当出现验证或转换错误时,提交的值将根本不显示。请注意,此构造对 JSF 输入组件无效(它已经在“幕后”这样做了)。

也可以看看:

ViewParam 与 @ManagedProperty(value = "#{param.id}")

JSF 2.0 中的通信 - 处理 GET 请求参数


@BalusC 与 faces-redirect=true 结合使用时,“bean”的范围应该是什么?如果范围设置为“@RequestScoped”,它会按预期工作吗?
@Geek:重定向会创建一个新的 GET 请求。源 bean 和目标 bean 的 bean 范围无关紧要。但是,您应该将新 GET 请求的可能影响考虑到请求并查看范围 bean。另请参阅stackoverflow.com/questions/7031885/…
@BalusC“但是,您应该将新的 GET 请求的可能影响考虑到请求并查看作用域 bean”到底是什么意思。
@Geek:它们将被丢弃并重新创建,因为它们的范围将结束并开始。
@BalusC。一个全面的答案。 “当您需要使用 '@'PostConstruct 之类的功能来查看并非在每个请求上调用的范围内的 bean 时,请检查该请求是否不是回发”。如果不是在每个请求上都调用它,那么为什么要检查请求是否是回发?
v
vuvo

将参数从视图发送到另一个视图,从发送者视图到接收者视图使用 viewParam 和 includeViewParams=true

在发件人中

声明要发送的参数。我们可以发送字符串、对象、……

发件人.xhtml

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

我们将发送参数 ID,它将包含在“includeViewParams = true”中,以返回单击按钮事件的字符串单击按钮触发 senderMB.clickBtnDetail(dto) 和来自 senderMB._arrData 的 dto

发件人.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) 中,我们使用从按钮事件 (dto) 获得的参数分配 _strID,这里是 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*

在接收器中

Get viewParam Receiver.xhtml 在Receiver中我们声明f:viewParam从get request(receive)中获取param,receiver的param名称必须和sender(page)相同

接收器.xhtml

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

它将从 sender View 获取 param ID 并分配给 receiver_MB._strID

使用 viewParam 在 Receiver 中,我们希望在页面渲染之前的 sql 查询中使用这个参数,以便我们使用 preRenderView 事件。我们不打算使用构造函数,因为构造函数将在接收到 viewParam 之前被调用所以我们添加

接收器.xhtml

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

进入 f:metadata 标签

接收器.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   
}

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅