簡體   English   中英

獲取GET請求參數到@ViewScoped bean

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM