0

スクリプトレットで定義されたメソッドで読み込まれた値を画面に表示する必要があります。以下のコードはコンパイルされません。

<%!
    void displayRecursively(KnowledgeElement ke, ExtendsRelationshipService ers){
        List<ExtendsRelationship> erList = null;
        %><%=ke.getName()%><br /><%!
        try {
            erList = ers.findIncomingExtendsKERelationships(ke);
        } catch (Exception e) {}
        if (erList!=null){
            for (ExtendsRelationship er : erList){
                KnowledgeElement startKe = er.getStartKE();
                displayRecursively(startKe,ers);
            }
        }
    } 
%>  

<%
    KnowledgeElement ke = null;
    ke = (KnowledgeElement)request.getAttribute("knowledgeElement");
    ExtendsRelationshipService ers = (ExtendsRelationshipService)request.getAttribute("ers");
    displayRecursively(ke,ers);             
%>

コンパイルエラーは次のとおりです。

PWC6199: Generated servlet error:
cannot find symbol
  symbol:   variable ke
  location: class org.apache.jsp.WEB_002dINF.ke_jsp

With .. %><%=ke.getName()%><% .. も同様にコンパイルされません。誰かがこれを解決する方法を提案できますか?

4

3 に答える 3

2

サーブレット コンテナは、次のアプローチに従って JSP コードをサーブレット クラスにコンパイルします。

  • 「<%! ... %>」スクリプトレット シンボルを使用すると、関数を定義できるサーブレット クラス自体の一部となるコードを定義することになります。
  • 「<% ... %>」スクリプトレット シンボルを使用すると、サーブレット自体の「サービス」メソッドの一部となるコードを定義することになります。

したがって、「サービス」メソッドの外側で宣言されているコードと、「サービス」メソッド内でコピーされる変数への参照を混在させています。

あなたの問題を解決するには、関数に別のパラメーターを追加し、その「相互参照」(またはそれを呼び出す必要があるもの) を置き換えます。次のようになります。

<%!
    void displayRecursively(JspWriter out, KnowledgeElement ke, ExtendsRelationshipService ers){
        List<ExtendsRelationship> erList = null;
        out.print(ke.getName());
        out.println("<br />");
        try {
            erList = ers.findIncomingExtendsKERelationships(ke);
        } catch (Exception e) {}
        if (erList!=null){
            for (ExtendsRelationship er : erList){
                KnowledgeElement startKe = er.getStartKE();
                displayRecursively(out, startKe,ers);
            }
        }
    } 
  %>

他のスクリプトレットでその関数を呼び出すときは、PrintWriter への参照を貼り付ける必要があります (これは、「サービス」メソッド内に入るスクリプトレットの暗黙の変数です)。

displayRecursively(out, ke, era);

コンパイルするには、JSP で「JspWriter」クラスのページ インポートが必要になることに注意してください。

于 2012-03-25T03:00:45.167 に答える
1

JSP スタイル ガイドがほぼ 10 年前に指摘したように:

タグ ライブラリが同等の機能を提供する場合は、可能な限り JSP スクリプトレットを使用しないでください。これにより、ページの読み取りと保守が容易になり、ビジネス ロジックをプレゼンテーション ロジックから分離しやすくなり、ページを JSP 2.0 スタイルのページに簡単に進化させることができます...

テンプレートを使用した再帰はトリッキーですが、実行できます。

これは、オブジェクトをELで消費できるものに適応させたり、例外を処理したりできるプレゼンテーション層オブジェクトです。

public class RelationshipPresentation {
  private final ExtendsRelationshipService service;
  private final ExtendsRelationship relationship;

  public RelationshipPresentation(ExtendsRelationshipService service, 
                                  ExtendsRelationship relationship) {
    this.service = service;
    this.relationship = relationship;
  }

  public String getName() { return relationship.getName(); }

  public List<RelationshipPresentation> getRelated() {
    List<RelationshipPresentation> list =
                                   new ArrayList<RelationshipPresentation>();
    try {
      for (ExtendsRelationship er :
           service.findIncomingExtendsKERelationships(relationship)) {
        list.add(new RelationshipPresentation(service, er));
      }
    } catch (Exception e) { /*Catching Exception?!*/ }
      return list;
  }
}

この型をマークアップから切り離して単体テストすることも簡単です。

これは、JSP にディスパッチする前にスコープに配置されます。

RelationshipPresentation relationshipPresentation =
                         new RelationshipPresentation(ers, knowledgeElement);
request.setAttribute("relationshipPresentation", relationshipPresentation);
getServletContext().getRequestDispatcher("/ercontainer.jsp")
                   .forward(request, response);

er.jsp次に示すのは、順序付けされていないリストで名前を表示する JSP フラグメント ( ) です。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:out value="${relationshipPresentation.name}" />
<ul>
    <c:forEach var="relationshipPresentation"
               items="${relationshipPresentation.related}">
        <c:set var="relationshipPresentation"
               value="${relationshipPresentation}" scope="request"/>
        <li><jsp:include page="er.jsp"/></li>
    </c:forEach>
</ul>

これは、JSP アクションを使用してメイン ページに含めることができます<jsp:include page="er.jsp" />

于 2012-03-25T12:07:32.007 に答える
0

<%!..%> は宣言タグと呼ばれます。service(<%..%>) の宣言タグで宣言された変数と定義されたメソッドを使用できますが、宣言タグからのメソッドのパラメーターは使用できません。

于 2012-03-25T03:46:43.800 に答える