Максимальная глубина <jsp: include> - PullRequest
2 голосов
/ 09 августа 2010

Мы используем сборку приложений с использованием Weblogic Workshop 10.3 и работаем на сервере Weblogic 10.3. Я пытаюсь отобразить дерево данных, используя рекурсивные вызовы на страницу JSP, используя <jsp:include>. Проблема, которую я имею, состоит в том, что после примерно 3-4 слоев глубина страницы больше не отображается. Операторы журнала вокруг JSP include показывают строки перед выполнением после, но jsp фактически никогда не включается. Операторы журнала в начале файла jsp указывают на то, что в этой точке не было достигнуто ни одной строки внутри jsp.

Ответы [ 2 ]

4 голосов
/ 09 августа 2010

Технически, предел зависит от производителя контейнеров сервлетов и доступной памяти кучи. Если вы зайдете слишком далеко, вы получите 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>");
        }
    }
}
0 голосов
/ 15 сентября 2010

Возможно, вам следует использовать правильный компонент дерева (Javascript Tree или библиотеку тегов) ???

...