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

有人能解释一下我们如何在一般情况下,或者在现实世界中使用这个代码片段吗?

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

处理 GET 参数

<f:viewParam>管理 GET 参数的设置、转换和验证。

以下示例

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

基本上是这样的:

  • 通过名称 id获取请求参数值。
  • 如果需要,转换并验证它(您可以使用 requiredvalidatorconverter属性,并像使用 <h:inputText>一样在其中嵌套 <f:converter><f:validator>)
  • 如果转换和验证成功,那么将其设置为由 #{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() {
// ...
}

然而,自从 JSF 2.2以来,<f:viewAction>是新的(<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豆:

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 并包含 ViewParams = true

在发件人

  1. 声明要发送的参数。我们可以发送字符串,对象,..。

Xhtml

<f:metadata>
<f:viewParam name="ID" value="#{senderMB._strID}" />
</f:metadata>
  1. 我们要发送参数 ID,它将包含在 “includeViewParams=true”返回字符串的点击按钮事件 单击按钮 fire senderMB.clickBtnDetail (dto) with dto from senderMB _ arrData

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*

在 Recever

  1. 获取视图 Param Xhtml 在 Receiver 中,我们声明 f: viewParam 来从 get request (接收)获取 param,接收方的 param 名称必须与 sender (页面)相同

Xhtml

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

它将从发送方视图中获取参数 ID,并将其分配给接收方 _ MB. _ strID

  1. 使用 viewParam 在 Receiver 中,我们希望在页面呈现之前的 sql 查询中使用这个参数,因此我们使用 preRenderView 事件。我们不打算使用构造函数,因为构造函数将在 viewParam 被接收之前被调用 所以我们加上

Xhtml

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

元数据标记

Xhtml

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

现在我们希望在 read 数据库方法中使用这个参数,可以使用它

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
}