4

JSTL forEach タグのかなり奇妙な動作を経験しました。

SessionBean と呼ばれる Bean があります。

public class SessionBean {
  private Collection<MyObject> objects;
  public Collection<MyObject> getObjects() {return objects;}
  ...
}

そして、そのような単純な JSP ページ:

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
    <f:view>
        <h:form>
            <c:forEach var="myObject" items="#{SessionBean.objects}">
                <h:outputText value="#{myObject}" /> <br />
            </c:forEach>
        </h:form>
    </f:view>
</body>

そして、それはうまくいきません。スローされる例外は

javax.servlet.jsp.JspTagException: <forEach> で指定された「アイテム」を反復処理する方法がわかりません
        org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEachIterator (ForEachSupport.java:255) で
        org.apache.taglibs.standard.tag.common.core.ForEachSupport.supportedTypeForEachIterator (ForEachSupport.java:219) で
   ....

なんで?
そして、items="#{SessionBean.objects}"items= に変更します"${SessionBean.objects}"が、例外はありません。MyObjects を除いて印刷されません。

次に、同じ変更を<h:outputText value="#{myObject}" />に加えましたが、この属性には無効な値です。

最後に、JSFoutputTextタグをに置き換えると${myObject}、期待どおりに機能します。

ここで各フェーズで何が起こるのか、誰か説明してもらえますか?

U: SessionBean は JSF によって管理されており、ヘッダーでいくつかのアクションを実行するため、作成されたことは間違いありません。

解決策:この問題は、J2EE 1.4 の JSTL と JSF の間の非互換性が原因であることが判明しました。J2EE 5 に切り替えると、最初のバリアントが問題なく動作するようになりました。

ありがとう!

4

1 に答える 1

5

この記事では、統合 EL と EL の違いについて説明します。ここにスニペットがあります

ELの評価

EL の評価は、即時評価と遅延評価に分類されます。即時評価とは、ページのレンダリング時に JSP ページが式を評価することを意味します。即時評価では、すべての値が常に読み取り専用になります。JSP EL 式は、${imExpr} の形式を取ります。JSP 式はすぐに評価されます。

遅延評価とは、統合 EL を使用するテクノロジーが JSP エンジンから式を評価する責任を引き継ぎ、ページのライフサイクル中の適切なタイミングで式を評価することを意味します。EL は JSP コンテナーから制御を取得し、適切なタイミングで式を評価します。JSF EL 式は #{defExpr} の形式を取ります。JSF 式はこのように機能します。

次の例は、ユーザーが値を入力するテキスト フィールド コンポーネントを表す JSF inputText タグを示しています。inputText タグの value 属性は、ブック Bean の name プロパティを指す式を参照します。

<h:inputText id="name" value="#{student.name}"/>

このタグを含むページの最初のリクエストの場合、JSF 実装は、ライフサイクルの「レスポンスのレンダリング」フェーズで #{student.name} 式を評価します。この段階では、式は、即時評価で行われるように、ブック Bean からの数量の値にアクセスするだけです。

ポストバックの場合、実装は「リクエスト値の適用」、「プロセスの検証」、および「モデルの更新」フェーズで式を評価します。その間に、値がリクエストから取得され、検証され、ブック Bean に伝播されます。

問題は、SessionBean のインスタンスが作成されなかったことにあるのでしょうか?

これを試して:

<jsp:useBean class="packagename.SessionBean" id="sb"/>
<c:forEach var="myObject" items="${sb.objects}">
            <h:outputText value="${myObject}" /> <br />
</c:forEach>

【追記】この記事が参考になるかな。2 つの EL がどのように連携するかを説明します。

于 2008-11-02T14:24:15.800 に答える