关于jsf:ViewParam与@ManagedProperty(值=“#{param.id}”))

ViewParam vs @ManagedProperty(value = “#{param.id}”)

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

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

然后像这样在ManagedBean中定义属性:

1
2
@ManagedProperty(value ="#{param.id}")
private Integer id;


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

  • 该设置值在@PostConstruct期间不可用,因此您需要在内附加一个以便根据设置值进行初始化/预加载。从JSF 2.2开始,您可以使用代替。

  • 允许嵌套进行更细粒度的转换/验证。甚至可以附加

  • 可以在任何URL中使用includeViewParams=true请求参数的includeViewParams属性作为GET查询字符串包含在内。

  • 可以在@RequestScoped Bean上使用,但是如果您希望视图参数能够承受由视图中包含的表单引起的任何验证失败,则要求Bean为@ViewScoped,否则,您需要手动保留针对该变量的所有请求参数。命令组件中的后续请求。

例:

1
2
3
4
5
6
7
<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" />

1
private User user;

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

@ManagedProperty

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

  • @PostConstruct期间可以使用设置值,从而可以根据设置值轻松初始化/预加载其他属性。

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

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

  • 如果依赖于后续POST请求中存在的#{param}托管属性,则需要将其作为包括在UICommand组件中。

例:

1
2
3
4
5
6
7
8
9
10
11
12
@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时,可以同时使用它们。您将只能再进行细粒度的转换/验证。

也可以看看:

  • 可以用来做什么?
  • JSF 2.0中的通信-处理GET请求参数


其他2个差异:

  • @ManagedProperty仅可用于JSF管理的bean,不适用于CDI(@Named)管理的bean;

    • 仅适用于GET请求的参数。