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

像这样定义View Params有什么区别:

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

在ManagedBean中定义属性如下:

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

<f:viewParam>

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

  • @PostConstruct设置的值是不可用的,所以你需要在<f:metadata>里面添加一个额外的<f:event type="preRenderView" listener="#{bean.init}" /> <f:metadata>来进行初始化/预加载设定值。 由于JSF 2.2你可以使用<f:viewAction>来代替。

  • 允许嵌套<f:converter><f:validator>进行更精细的转换/validation。 甚至可以附加一个<h:message>

  • 可以在任何URL中使用<h:link> includeViewParams属性或includeViewParams=true请求参数作为GET查询string。

  • 可以在@RequestScoped bean上使用,但是如果您希望视图参数能够在视图中包含的窗体引起的任何validation失败后仍然存在,那么它需要该bean为@ViewScoped ,否则您需要手动保留后续请求的所有请求参数由命令组件中的<f:param>指定。

例如

 <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中可用,可以根据设置值轻松地对其他属性进行初始化/预加载。

  • 不允许在视图中进行声明性转换/validation。

  • #{param}托pipe属性在范围比请求范围更广的bean上是不允许的,所以这个bean必须是@RequestScoped

  • 如果您依赖于#{param}的托pipe属性出现在后续的POST请求中,那么您需要将其作为<f:param>UICommand组件中。

例如

 @ManagedProperty("#{param.id}") private Long id; private User user; @EJB private UserService userService; @PostConstruct public void init() { user = userService.find(id); } 

但是,你必须通过摆弄FacesContext#addMessage()或其他东西来pipe理validation。


@PostConstructincludeViewParams都是强制的时,你可以使用它们。 您将不能再应用细粒度的转换/validation。


也可以看看:

  • 什么可以使用<f:元数据>,<f:viewParam>和<f:viewAction>?
  • JSF 2.0中的通信 – 处理GET请求参数

2其他区别:

  • @ManagedProperty仅适用于由JSFpipe理的bean,不适用于由CDIpipe理的bean( @Named );
    • <f:viewParam>仅适用于GET请求的参数。