JSTL forEachタグ:列挙の問題、およびその動作方法の理解
質問
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: Don't know how to iterate over supplied "items" in <forEach> at org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEachIterator(ForEachSupport.java:255) at org.apache.taglibs.standard.tag.common.core.ForEachSupport.supportedTypeForEachIterator(ForEachSupport.java:219) ....
なぜ?
次に、items="#{SessionBean.objects}"
をitems = "${SessionBean.objects}"
に変更しますが、例外はありません。 MyObjectsを除き、印刷されません。
次に、<h:outputText value="#{myObject}" />
に同じ変更を加えますが、この属性の値は無効です。
最後に、JSF outputText
タグを${myObject}
だけに置き換えると、期待どおりに動作します。
誰かが説明できますか、各フェーズでここで何が起こりますか?
U: SessionBeanはJSFによって管理され、ヘッダーでいくつかのアクションを実行するため、確実に作成されました。
解像度:この問題は、J2EE 1.4のJSTLとJSFの非互換性が原因であることが判明しました。 J2EE 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実装は<!> quot; render response <!> quot;の間に#{student.name}式を評価します。ライフサイクルのフェーズ。このフェーズでは、即時評価で行われるように、式はブックBeanから数量の値にアクセスするだけです。
ポストバックの場合、実装は<!> quot; apply request values、<!> quot;の間に式を評価します。 <!> quot;プロセス検証、<!> quot;および<!> quot;モデルの更新<!> quot;フェーズ。値はリクエストから取得され、検証され、ブック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がどのように連携するかを説明しています。