非请求范围Bean中的@ManagedProperty(value =“#{param.id}”)

我需要将参数(POST)传递给@managedBean,我使用了像这样的托管属性:

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

Bean的范围是ViewScope

我最终得到了这个错误:

无法创建托管bean收据。 发现了以下问题: – 表达式#{param.id},request引用的对象的范围比引用的托管bean范围短

我能做什么?

arjan看看:

我的页面:Facelet Title

 

两种方式:

  1. 使bean请求作用域并将视图作用域注入另一个@ManagedProperty

     @ManagedBean @RequestScoped public class RequestBean { @ManagedProperty(value="#{param.id}") private Integer id; @ManagedProperty(value="#{viewBean}") private ViewBean viewBean; } 

    视图范围bean在@PostConstruct和请求范围bean的操作方法期间可用。 您只需要记住,在没有参数的情况下回发到同一视图时, id可能会丢失。

  2. 或者,在bean初始化期间从请求参数映射中手动获取它。

     @ManagedBean @ViewScoped public class ViewBean { private Integer id; @PostConstruct public void init() { id = Integer.valueOf(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id")); } } 

    这样,初始id在整个视图范围内都可用。

作为直接从bean中的请求获取参数的替代方法,您可以使用view parameters

这些需要在使用托管bean的Facelet上声明,如下所示:

         

如果您现在请求此页面,将使用为id参数提供的请求值调用辅助bean的setter。 这适用于GET和(非面) POST请求。

优点是您可以在此处使用标准JSF转换器和validation器。 当然,如果您的托管bean没有绑定到特定视图,那么此解决方案不太理想。

需要注意的一个小特点是,在提供视图参数的初始请求之后进行正常面向回发时,将再次调用bean中的setter,即使bean在视图范围内并且没有明确的新值提供。

为了测试这是否有效,我使用了以下托管bean:

 import javax.annotation.PostConstruct; import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; import javax.faces.event.ActionEvent; @ManagedBean @ViewScoped public class MyBean { Long id; @PostConstruct public void test() { System.out.println("post construct called"); } public void actionMethod(ActionEvent event) { System.out.println("action called"); } public Long getId() { return id; } public void setId(Long id) { this.id = id; } } 

以下Facelet:

          

在输入字段中输入一个数字,然后单击“提交”按钮。 如果数字打印在屏幕上,则测试成功。 请注意,第二个表单是常规表单,不会发布任何JSF状态。 我在JBoss AS 6上测试了这个并且它可以工作。 将id参数certificate为GET参数也可以。