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

Posted

技术标签:

【中文标题】ViewParam 与 @ManagedProperty(value = "#param.id")【英文标题】:ViewParam vs @ManagedProperty(value = "#param.id")ViewParam 与 @ManagedProperty(value = "#param.id") 【发布时间】:2011-06-20 19:26:52 【问题描述】:

这样定义视图参数有什么区别:

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

并像这样在 ManagedBean 中定义属性:

@ManagedProperty(value = "#param.id")
private Integer id;

【问题讨论】:

【参考方案1】:

2 其他差异:

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

【讨论】:

因此可以使用注解:org.omnifaces.cdi.Param【参考方案2】:

&lt;f:viewParam&gt;:

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

设置值在@PostConstruct期间不可用,因此您需要在&lt;f:metadata&gt;内额外添加&lt;f:event type="preRenderView" listener="#bean.init" /&gt;,以根据设置值进行初始化/预加载。从 JSF 2.2 开始,您可以使用 &lt;f:viewAction&gt; 代替。

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

可以使用&lt;h:link&gt;includeViewParams=true 请求参数的includeViewParams 属性作为GET 查询字符串包含在任何URL 中。

可以在@RequestScoped bean 上使用,但如果您希望视图参数在视图中包含的表单导致的任何验证失败中幸存下来,则它需要 bean 为@ViewScoped,否则您需要手动保留所有请求命令组件中&lt;f:param&gt;后续请求的参数。

示例

<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 期间可用,它允许根据设置值轻松初始化/预加载其他属性。

不允许在视图中进行声明式转换/验证。

#param 的托管属性不允许在比请求范围更广的 bean 上使用,因此 bean 必须是 @RequestScoped

如果您依赖 #param 的托管属性出现在后续 POST 请求中,则需要将其作为 &lt;f:param&gt; 包含在 UICommand 组件中。

示例

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

private User user;

@EJB
private UserService userService;

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

但是当usernull 时,您必须自己管理验证,通过摆弄FacesContext#addMessage() 或其他东西。


@PostConstructincludeViewParams 都是必需的时,您可以同时使用它们。您将无法再应用细粒度的转换/验证。


另见:

What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for? Communication in JSF 2.0 - Processing GET request parameters

【讨论】:

在特殊情况下还有其他方法可以检索请求参数:FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("parametername"); @angel:仅当 bean 的范围比请求范围更广时,才会使请求参数上的@ManagedProperty 成为不可能。 嗨@BalusC 我确实依赖于在第二篇文章中使用 managedproperty 从 param.id 检索到的 id 值。如何使用 f:param 包含它?非常感谢 @thufir:在更新模型值阶段设置。 postconstruct 远早于此,直接在 bean 的构造和依赖注入之后运行。它在由 &lt;f:event type="preRenderView"&gt; 或即将推出的 JSF 2.2 &lt;f:viewAction&gt; 调用的侦听器方法中可用。 @feder: ***.com/questions/7794149/…

以上是关于ViewParam 与 @ManagedProperty(value = "#param.id")的主要内容,如果未能解决你的问题,请参考以下文章

f:viewParam 具有多个值

f:viewParam 在 ajax 调用后丢失

JSF bean:设置 ViewParam 后调用 @PostConstruct 函数

根据 f:viewParam 有条件地调用 f:viewAction

何时调用 <f:metadata><f:viewParam> 的设置器

如何在不调用 <f:viewparam> 转换器的情况下调用 setter?