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

101

如何定义View Params有什么区别:

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

在ManagedBean中这样定义属性:

@Inject @ManagedProperty(value = "#{param.id}")
private Integer id;
2个回答

148

<f:viewParam>

  • 仅在更新模型值阶段设置值(因为它扩展了UIInput)。

  • @PostConstruct期间不可用,因此您需要在<f:metadata>内部使用一个额外的<f:event type="preRenderView" listener="#{bean.init}" />根据设置的值进行初始化/预加载。自JSF 2.2以来,您可以使用<f:viewAction>代替。

  • 允许嵌套<f:converter><f:validator>进行更细粒度的转换/验证。甚至可以附加<h:message>

  • 可以使用includeViewParams属性的<h:link>includeViewParams=true请求参数中的任何URL自动包含为GET查询字符串的目标URL。

  • 可以用于@RequestScoped bean,但如果要使视图参数在由视图封装的表单引起的任何验证失败后保留,则需要将bean设置为@ViewScoped,否则您需要通过UICommand组件中的<f:param>手动保留所有请求参数,因为每个请求都将设置<f:viewParam>

例子:

<f:metadata>
    <f:viewParam id="user_id" name="id" value="#{bean.user}"
        required="true" requiredMessage="Invalid page access. Please use a link from within the system."
        converter="userConverter" converterMessage="Unknown user ID."
    />
</f:metadata>
<h:message for="user_id" />

使用

private User user;

有一个@FacesConverter("userConverter")。通过http://example.com/context/user.xhtml?id=123调用页面将通过转换器传递id参数并将User对象设置为bean属性。


@ManagedProperty:

  • 设置bean构造后立即的值。

  • @PostConstruct期间设置的值可用,这允许根据设置的值轻松初始化/预加载其他属性。

  • 不支持在视图中进行声明式转换/验证。

  • 不支持自动包含在结果目标URL中。

  • 可以用于任何范围的bean,但它只会在bean的构造过程中设置,而不是在每个请求中设置。

示例

@Inject @ManagedProperty("#{param.id}")
private Long id;

private User user;

@EJB
private UserService userService;

@PostConstruct
public void init() {
    user = userService.find(id);
}

请注意,当user为空时,您需要通过在@PostConstruct方法中使用FacesContext#addMessage()来管理转换和验证。还要注意,当#{param.id}不是有效数字时,在命中@PostConstruct之前会抛出异常。如果您想处理它,那么最好将其设置为private String id。但更好的方法是使用<f:viewParam>
你可以在必须使用@PostConstructincludeViewParams时同时使用它们。但是,你将不能再应用精细的转换/验证。

参见:


1
在特殊情况下,还有其他替代方法来检索请求参数:FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("parametername"); - angelcervera
1
@angel: 仅当Bean具有比请求范围更广的作用域时,才会使请求参数上的@ManagedProperty无法使用。 - BalusC
1
@thufir:它是在更新模型值阶段设置的。postconstruct 在此之前运行,直接在 Bean 构建和依赖注入后运行。它可以在由<f:event type="preRenderView">调用的监听器方法中使用,或者在即将到来的 JSF 2.2 <f:viewAction>中使用。 - BalusC
你可以使用f:viewParam来处理多个GET参数吗? - feder
1
@feder:https://dev59.com/questions/2VzUa4cB1Zd3GeqP10xS - BalusC
显示剩余2条评论

6

还有两点不同之处:

  • @ManagedProperty 只能用于被JSF管理的bean,不能用于被CDI (@Named) 管理的bean;
    • <f:viewParam> 仅适用于GET请求的参数。

1
因此,您可以使用注释:org.omnifaces.cdi.Param。 - dforce

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接