Когда скриптлеты (jsp) запускают свой (Java) код?

Я работал с исключением нулевого указателя в коде, подобном следующему:

<%
SessionData session = getSessionData(request);
Webpage webPage = null;
if (session!= null) {
    webPage = session.getWebPage();
}
%>

<script type="text/javascript"> 

//NullPointer happens here, webPage is null when the session is lost
<tags:ComboBox
    comboBox="<%=webPage.getComboBox()%>" />

</script>

Я был удивлен, когда смог переместить окончание if (session!=null после javascript, который, кажется, игнорирует этот код, когда сеанс был нулевым.

<%
SessionData session = getSessionData(request);
Webpage webPage = null;
if (session!= null) {
    webPage = session.getWebPage();
//} move this to below
%>

<script type="text/javascript"> 

//NullPointer happens here, webPage is null when the session is lost
<tags:ComboBox
    comboBox="<%=webPage.getComboBox()%>" />

</script>
<% } %> //moved to here

Скриптлет для тега ComboBox в скобках больше не запускается? Я бы подумал, что он все равно попытается убрать поле со списком с веб-страницы и все равно получит нулевой указатель. Я ошибаюсь, думая, что все скриптлеты получают свои значения до фактического запуска кода?

(просто хотел упомянуть, что есть включенный скрипт, который перенаправляет страницу, если нет сеанса. Я получаю NullPointer с первым разделом кода и правильно перенаправляю со вторым разделом)


person DoubleDouble    schedule 09.09.2015    source источник


Ответы (2)


JSP компилируется в сервлет на лету контейнером сервлетов.

Эта компиляция на самом деле представляет собой простую инверсию:

TEXT1
<% java code %>
TEXT2
<%= java expression %>
TEXT3

Это компилируется в:

out.print("TEXT1");
java code
out.print("TEXT2");
out.print(java expression);
out.print("TEXT3");

Итак, когда вы говорите:

TEXT1
<% if (true) { %>
TEXT2
<% } %>
TEXT3

Ты получаешь:

out.print("TEXT1");
if (true) {
out.print("TEXT2");
}
out.print("TEXT3");

Приведенные выше примеры минимизированы для ясности, например. символы новой строки игнорируются, стандартная настройка сервлета не включена, а сложность выполнения библиотеки тегов не рассматривается.

person Andreas    schedule 09.09.2015

Короче говоря, вы ошибаетесь в отношении порядка, в котором обрабатываются библиотеки тегов и скриптлеты; компилятор JSP сначала идентифицирует директивы JSP, затем разрешает и отображает выходные данные библиотеки тегов, а затем преобразует все, что не входит в скриптлет, в набор статических строк, записанных на страницу, прежде чем сшивать полученный файл Java вместе с существующим кодом скриптлета, глядя что-то нравится:

// start of class and _jspService method declaration omitted for brevity

    out.write("<html>\n");
    out.write("\t<head>\n");
    out.write("\t<title>Example Static HTML</title>\n");

// comment inside a scriptlet block
int x = request.getParameter("x");
pageContext.setParameter("x", x);

    out.write("\t</head>\n");

Проблема здесь связана с тем, что сначала разрешаются библиотеки тегов, а код, который изолирует и оценивает их, не заботится ни о блоках скриптлетов, ни о DOM. В вашем случае тег <tags:ComboBox> просто считает скриптлет обычной строкой.

Вместо этого вы должны предоставить значение в вашем скриптлете доступной области, используемой библиотекой тегов; в случае с JSTL, например, нужно добавить его в контекст страницы через pageContext.setAttribute("varName", value).

Проверьте этот ответ для получения более подробной информации.

person Shotgun Ninja    schedule 09.09.2015