Максимальная глубина <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 или библиотеку тегов)???

Другие вопросы по тегам