3

次のメソッドを持つ ViewScoped Bean があります。

public Item getItem()  
{
     try {
          itemID = Integer.parseInt(
             FacesContext.getCurrentInstance().getExternalContext()
                         .getRequestParameterMap().get("itemID"));  
     } catch(NumberFormatException ex) {
          FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(
                       FacesMessage.SEVERITY_ERROR, "Item lookup error", null));
          return null;  
     }  
     return itemsDAO.findByID(itemID);
}

このメソッドは ViewID パラメータを受け取り、 を使用してオブジェクトを検索しますitemsDAONumberFormatExceptionをキャッチしてそこにメッセージを追加することにより、itemID が整数でない場合に FacesMessage を表示したかったのです。ただし、これは機能しません。上記FacesMessageのコード スニペットは、次のビュー タグ内ではレンダリングされません。h:messages globalOnly="true" infoClass="info" errorClass="error"

メソッドが呼び出されるまでに が利用できないと思わFacesContextれますが、この例外を処理する方法がわかりません。

更新 1:

viewParam を使用して組み込みの変換と検証を利用するという提案について。この場合、これがどのように機能するかわかりません。itemID は、以下に示すようにすべてのアイテムが一覧表示される「インデックス」ビューから渡されます。各アイテムのタイトルは、URL を介して渡される itemID を持つ viewItem ページへのリンクです。この場合、index ビューに多くのアイテムがある場合、viewParam を使用して itemID を viewItem ビューに渡すにはどうすればよいですか?

index.xhtml

<code>
 <ui:repeat var="item" value="#{ItemViewBean.items}">
       <div id="item">
        <h:link value="#{item.title}" outcome="viewItem">
        <f:param name="itemID" value="#{item.id}"></f:param>
        </h:link>
        <p><h:outputText value="#{item.description}"></h:outputText> <br />
        Address: <h:outputText value="#{item.address}"></h:outputText></p>
        <span class="itemFooter">
        Submitted By: <h:outputText value="#{item.user.username}"></h:outputText> On
        <h:outputText value="#{item.postDate}"></h:outputText>
        </span>
       <hr />
       </div>
       </ui:repeat>
</code>

更新 2: この問題の回避策を 1 つ思いつきました。例外が発生した場合は、エラー FacesMessage を Flash オブジェクトに入れ、何らかのエラー ページにリダイレクトします。FacesMessage を FacesContext に単純に追加してビューに表示できない理由はまだわかりません。

4

1 に答える 1

3

をトラバースしていることを考えるとExternalContext#getRequestParameterMap()、GET リクエストを傍受しているようです。getterメソッドで行われることを考えると(悪い!!)、itemプロパティを参照するコンポーネントがレンダリングされる場合にのみ実行されるようです。

したがって、上記の仮定が正しいと仮定すると、この問題は、プロパティを参照するコンポーネントの<h:messages>にコンポーネントがビューで宣言されたときに明らかになります。つまり、顔のコンテキストに新しいメッセージを追加するには遅すぎます。その時点で、つまりすでにレンダリングされています。item<h:messages>

少なくとも、この特定の問題の症状に一致する他の合理的な原因は考えられません。この問題には基本的に 2 つの解決策があります。

  1. プロパティを参照するコンポーネントのに を移動し<h:messages>て、faces メッセージが追加された後にレンダリングされるようにします。item

  2. リクエスト パラメータを Bean プロパティとして設定するために<f:event>、できれば と組み合わせて、レンダリング前のビュー イベント中にビジネス ジョブを実行します。悪いゲッター アプローチの唯一の仕事が値の変換であることを考えると、 a をコンバーターと組み合わせて<f:viewParam>単独で使用することもできます。<f:viewParam>

言うまでもなく、現在、いくつかの基本的な JSF 概念を基本的に乱用/回避していることを考えると、オプション 2 が優先されます。とりわけ、ビジネスロジックはゲッターに属していません。

例えば

<f:metadata>
    <f:viewParam id="itemID" name="itemID" value="#{bean.item}"
        required="true" requiredMessage="Invalid page access. Please use a link from within the system."
        converter="itemConverter" converterMessage="Unknown item ID."
    />
</f:metadata>
<h:message for="itemID" />

private Item item; // +getter +setter

これは、リクエストパラメータがメソッド内のインスタンスに変換されるitemConverter単なるConverter実装です。ItemgetAsObject()

以下も参照してください。

于 2013-01-06T23:29:05.687 に答える