获取GET请求参数到@ViewScoped bean

我有一个(请求范围的)列表,用户可以从中选择“PQ”(链接列表)。 单击或以其他方式输入浏览器时,将显示每个PQ的主页面。 每个PQ的页面都是表格

http://localhost:8080/projectname/main.jsf?id=2

这是PQ bean的第一个:

 @Named @ViewScoped public class PqHome implements Serializable { @PersistenceContext(unitName="...") private EntityManager em; private Integer id; private PQ instance; @PostConstruct public void init() { System.out.println("ID is " + id); // ID from URL param instance = em.find(PQ.class, id); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public PQ getInstance() { return instance; } } 

这是main.xhtml:

             ...  

每当我选择或以其他方式刷新页面/ URL时,我都会从EntityManager获得NullPointerException

 org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public de.mycomp.myproj.beans.PqHome.init() on de.mycomp.myproj.beans.PqHome@4f0ea68f at org.jboss.weld.bean.AbstractClassBean.defaultPostConstruct(AbstractClassBean.java:595) ... Caused by: java.lang.IllegalArgumentException: id to load is required for loading at org.hibernate.event.spi.LoadEvent.(LoadEvent.java:87) at org.hibernate.event.spi.LoadEvent.(LoadEvent.java:59) at org.hibernate.internal.SessionImpl.get(SessionImpl.java:961) at org.hibernate.internal.SessionImpl.get(SessionImpl.java:957) at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:787) at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:762) at org.jboss.as.jpa.container.AbstractEntityManager.find(AbstractEntityManager.java:221) at de.mycomp.myproj.beans.PqHome.init(PqHome.java:47) ... 56 more 

[第47行是em.find(…)]

这条线

  

不会让事情变得更好。 我现在很沮丧。

如何将URL GET请求参数传入@ViewScoped bean?

注意 :我敢打赌这不是一件容易的事。 有可能我在概念上做错了,所以欢迎任何有关如何改进的提示。 我觉得我需要选择@ViewScoped因为在@ViewScoped会有更复杂的基于AJAX的GUI,我真的希望通过URL GET参数保持访问。

谢谢

在构造bean和所有dependency injection之后直接调用@PostConstruct (例如@PersistenceContext,@ EJB,@ ManagedProperty,@ Inject等等。)。

在更新模型值阶段设置其值,该阶段是bean的远期(后)构造。 因此,在@PostConstruct ,尚未设置值。 那时它仍然是null

您接近 ,但您必须删除 @PostConstruct注释。

所以:

     

 private Integer id; public void init() { instance = em.find(PQ.class, id); } 

具体问题无关 ,我建议使用Converter代替。 另请参见JSF 2.0中的通信 – 转换和validationGET请求参数 。

@Named @ViewScoped组合也不会按预期工作。 特定于JSF的@ViewScoped仅与JSF特定的@ManagedBean结合使用。 您的CDI特定@Named将以这种方式表现为@RequestScoped 。 使用@ManagedBean而不是@Named或使用CDI特定的@ConversationScoped而不是@ViewScoped

有一种更好的方法从url获取id。 只需在@PostConstruct init()方法中使用它从url获取“id”:

 FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"); 

您仍然可以使用ViewScoped和@PostConstruct。