我需要在屏幕上显示一些在script-let中定义的方法中读取的值。下面的代码没有编译:
<%!
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
使用..%&gt;&lt;%= ke.getName()%&gt;&lt;%..也不会编译。 有人可以建议如何解决这个问题吗?
答案 0 :(得分:2)
Servlet容器按照这种方法将JSP代码编译成servlet类:
所以,你正在做的是将在“service”方法之外声明的代码与对将要在“service”方法中复制的变量的引用混合。
要解决您的问题,我会在您的函数中添加另一个参数,并替换“交叉引用”(或者应该调用它)。它看起来像这样:
<%!
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);
}
}
}
%>
在您的其他scriptlet中调用该函数时,您必须在对PrintWriter的引用中过去(这是对于“service”方法内部的scriptlet的隐式变量):
displayRecursively(out, ke, era);
请注意,您需要在JSP中对“JspWriter”类进行页面导入才能进行编译。
答案 1 :(得分:1)
作为JSP样式指南noted nearly a decade前:
尽可能在标记库提供等效功能时避免使用JSP scriptlet。这使得页面更易于阅读和维护,有助于将业务逻辑与表示逻辑分离,并使您的页面更容易演变为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);
这是一个JSP片段(er.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" />
包含在您的主页中。
答案 2 :(得分:0)
&LT;!%..%GT;被称为声明性标签。您可以使用声明的变量和在service(&lt;%..%&gt;)中的声明性标记下定义的方法,但不能使用声明性标记中的方法参数。