3

ユーザーが「PQ」(リンクのリスト)を選択できる(リクエストスコープの)リストがあります。クリックするか、ブラウザに入力すると、各PQのメインページが表示されます。各PQのページは次の形式です

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

最初のPQBeanは次のとおりです。

@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を選択または更新するたびに、 :NullPointerExceptionから取得します。EntityManager

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}" />

物事を良くすることはありません。私は今かなり絶望的です。

どのようにしてURLGETリクエストパラメータを@ViewScopedBeanに取り込みますか?

:それは簡単なことではないと思います。概念的にここで何か間違ったことをしている可能性があるので、改善するためのヒントを歓迎します。@ViewScopedそのページには、URL GETパラメーターを介してアクセスできるようにしておきたいより複雑なAJAXベースのGUIがあるため、選択する必要があると感じました。

ありがとう

4

2 に答える 2

7

URLからIDを取得するためのより良い方法があります。@PostConstruct init()メソッドで使用して、URLから「id」を取得します。

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

ViewScopedと@PostConstructは引き続き使用できます。

于 2012-03-23T15:34:15.313 に答える
6

は、Beanの構築とすべての依存性注入(、、、、など)の直後@PostConstruct呼び出されます。@PersistenceContext@EJB@ManagedProperty@Inject

<f:viewParam>は、Beanの(後)構築のはるか後のモデル値の更新フェーズ中にその値を設定します。したがって、値の内部では@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「 JSF2.0での通信-GET要求パラメータの変換と検証」も参照してください。

また、この組み合わせ@Named @ViewScopedは意図したとおりに機能しません。JSF固有@ViewScopedは、JSF固有との組み合わせで@ManagedBeanのみ機能します。CDI固有@Namedはこのように動作@RequestScopedします。@ManagedBeanの代わりに使用するか、の代わりに@NamedCDI固有を使用してください。@ConversationScoped@ViewScoped

于 2011-10-11T12:41:44.703 に答える