[英]Getting a GET request param into an @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:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
...>
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="id" value="#{pqHome.id}">
<f:convertNumber integerOnly="#{true}" />
</f:viewParam>
<!--f:event type="preRenderView" listener="#{pqHome.init}" /-->
</f:metadata>
</ui:define>
<ui:define name="title">
<h:outputText value="Main" />
</ui:define>
...
</ui:composition>
每當我選擇或以其他方式刷新頁面/ 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.<init>(LoadEvent.java:87)
at org.hibernate.event.spi.LoadEvent.<init>(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(...)]
這條線
<f:event type="preRenderView" listener="#{pqHome.init}" />
不會讓事情變得更好。 我現在很沮喪。
如何將URL GET請求參數傳入@ViewScoped
bean?
注意 :我敢打賭這不是一件小事。 有可能我在概念上做錯了,所以歡迎任何有關如何改進的提示。 我覺得我需要選擇@ViewScoped
因為在@ViewScoped
會有更復雜的基於AJAX的GUI,我真的希望通過URL GET參數來訪問它。
謝謝
該@PostConstruct
是bean的建設和所有依賴注入(如后直接調用@PersistenceContext
, @EJB
, @ManagedProperty
, @Inject
,etc..etc ..)。
<f:viewParam>
在更新模型值階段設置其值,這是在bean構建之后<f:viewParam>
(后)。 因此,在@PostConstruct
,尚未設置<f:viewParam>
值。 那時它仍然是null
。
您已接近<f:event type="preRenderView">
,但您必須刪除 @PostConstruct
注釋。
所以:
<f:viewParam name="pq" value="#{pqHome.id}">
<f:convertNumber integerOnly="#{true}" />
</f:viewParam>
<f:event type="preRenderView" listener="#{pqHome.init}" />
同
private Integer id;
public void init() {
instance = em.find(PQ.class, id);
}
與具體問題無關 ,我建議使用Converter
代替。 另請參見JSF 2.0中的通信 - 轉換和驗證GET請求參數 。
@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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.