Технически, предел зависит от производителя контейнеров сервлетов и доступной памяти кучи. Если вы зайдете слишком далеко, вы получите 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>
Стандартная установка Tomcat 6.0.24 с максимальной памятью кучи по умолчанию 64 МБ начала давать ошибки после ~ 200 включений.
Чтобы обойти это, вам нужно иметь итеративное включение, а не рекурсивное включение. в этом может помочь JSTL c:forEach
.
Обновление : Я не уверен насчет Weblogic, но Tomcat записывает stderr в файл, отличный от stdout. Что касается глубины, Weblogic может быть тяжеловесным сервером. Перед включением JSP может быть много предшествующих вызовов методов.
Если итерация не является решением, то ваш единственный вариант - хвостовая рекурсия . По сути, передайте результат как аргумент метода, а не полагайтесь на (ожидая) возвращаемое значение метода, таким образом сохраняя стек. К сожалению, это невозможно при использовании обычного 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>");
}
}
}