最大<jsp:include>深度</jsp:include>

时间:2010-08-09 13:40:56

标签: java jsp recursion weblogic jspinclude

我们正在使用Weblogic Workshop 10.3进行应用程序构建,并在weblogic服务器10.3上运行。我正在尝试使用<jsp:include>使用递归调用jsp页面来显示数据树。我遇到的问题是,在大约3-4层之后,页面不再被渲染。 JSP周围的日志语句包括在执行之后显示行,但jsp实际上从未被包含。 jsp文件开头的日志语句表明此时没有到达jsp中的一行。

2 个答案:

答案 0 :(得分:4)

从技术上讲,限制取决于servletcontainer make和可用堆内存。如果你走得太远,你会得到一个StackOverflowError。如果您错过了它,请再次检查服务器特定的错误日志。

我使用以下片段玩游戏:

test.jsp

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>SO question 3440560</title>
    </head>
    <body>
        <jsp:include page="include.jsp?count=${param.count}" />
    </body>
</html>

include.jsp

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:if test="${param.count > 0}">
    <p>include ${param.count}</p>
    <jsp:include page="include.jsp?count=${param.count - 1}" />
</c:if>

默认最大堆内存为64MB的标准Tomcat 6.0.24安装程序在~200包含后开始出错。

要解决这个问题,你希望有一个迭代包含而不是递归包含。 JSTL c:forEach可能对此有所帮助。


更新:我不确定Weblogic,但Tomcat将stderr记录到与stdout不同的文件。至于深度,Weblogic可能是一个重量级的服务器。在包含JSP之前,可能会有许多前面的方法调用。

如果迭代不是解决方案,那么您唯一的选择就是tail recursion。基本上,将结果作为方法参数传递而不是依赖(等待)方法的返回值,这样就可以保存堆栈。遗憾的是,使用普通jsp:include是不可能的。您想编写标记文件和/或帮助程序类。

基本上如下:

public void renderHTML(List<Node> nodes, StringBuilder output) { 
    output.append("<li>" + node.getContent() + "</li>"); 
    for (Node node : nodes) {
        if (node.hasChildren()) {
            output.append("<ul>");
            renderHTML(node.getChildren(), output);
            output.append("</ul>");
        }
    }
}

答案 1 :(得分:0)

也许您应该使用正确的树组件(Javascript树或标记库)???