Максимальная глубина <jsp: include>
Мы используем сборку приложений с использованием Weblogic Workshop 10.3 и работаем на сервере Weblogic 10.3. Я пытаюсь отобразить дерево данных с помощью рекурсивных вызовов на страницу JSP с помощью <jsp:include>
, Проблема, которую я имею, состоит в том, что после примерно 3-4 слоев глубина страницы больше не отображается. Операторы журнала вокруг JSP include показывают строки перед выполнением после, но jsp фактически никогда не включается. Операторы журнала в начале файла jsp указывают на то, что в этой точке не было достигнуто ни одной строки внутри jsp.
2 ответа
Технически, предел зависит от производителя сервлет-контейнера и доступной памяти кучи. Если вы зайдете слишком далеко, вы получите StackruError
, Если вы пропустили этот шанс, проверьте журналы ошибок сервера еще раз.
Я играл вокруг, используя следующие фрагменты:
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>");
}
}
}
Возможно, вам следует использовать правильный компонент дерева (Javascript Tree или библиотеку тегов)???