В этой главе описаны синтаксис ядра и семантика спецификации JavaServer Pages 1.2 (JSP 1.2).
JSP-страница это текстовый документ, который описывает, как создавать объект response
из объекта request для данного протокола. Процессинг JSP-страницы может
включать создание и/или использование других объектов.
JSP-страница определяет класс реализации JSP-страницы который реализует
семантику JSP-страницы. Этот класс является подклассом Servlet'а (см.
Главу JSP.8). Во время запроса, запрос, предназначенный для JSP-страницы,
направляется объекту реализации JSP-страницы для обработки/процесинга.
HTTP является протоколом по умолчанию для запросов и ответов. Дополнительные
протоколы запроса/ответа могут поддерживаться JSP-контейнерами (см. ниже).
Объекты request
и response
по умолчанию имеют тип HttpServletRequest
и
HttpServletResponse
, соответственно.
JSP-контейнер это экземпляр системного уровня, предоставляющий
обслуживание жизненного цикла и поддержку на этапе прогона для JSP-страниц Servlet-компонентов.
Запросы, направляемые JSP-странице, направляются JSP-контейнером подходящему
объекту реализации JSP-страницы. Термин web-контейнер
является синонимом JSP-контейнера.
Web-компонент это сервлет или JSP-страница. Элемент servlet
в дескрипторе публикации
web.xml используется для описания обоих типов web-компонентов. Компоненты - JSP-страницы
- определяются неявно в дескрипторе публикации через использование неявного
отображения расширения .jsp
JSP-страницы имеют эквивалент - XML-документ. XML-просмотр JSP-страницы создан для фазы трансляции
(см. ниже).
JSP-страница может быть написана сразу как XML-документ. Начиная с версии JSP
1.2, XML-документ может быть направлен JSP-контейнеру для процесинга.
Нельзя смешивать стандартный синтаксис и XML-синтаксис в одном файле-источнике.
Однако JSP-страница любого синтаксиса может включать JSP-страницу любого
синтаксиса через директиву.
JSP-контейнер обслуживает две фазы существования JSP-страницы. В фазе трансляции
контейнер определяет класс реализации JSP-страницы, соответствующий JSP-странице.
В фазе выполнения контейнер обслуживает один или более экземпляров этого класса
в ответ на запрос и другие события.
Во время фазы трансляции контейнер локализует или создаёт класс
реализации JSP-страницы, соответствующий данной JSP-странице. Этот процесс
определяется семантикой JSP-страницы. Контейнер интерпретирует имеющиеся на этой
странице стандартные директивы и акции и специальные акции, ссылающиеся на
библиотеки тэгов. Библиотека тэгов может по выбору представлять метод проверки
корректности использования на JSP-странице данной библиотеки.
JSP-контейнер гибко работает с деталями класса реализации JSP-страницы, что
может использоваться для адресации вопросов quality-of-service/качества-сервиса.
В фазе выполнения
JSP-контейнер направляет события объекту реализации JSP-страницы. Контейнер
отвечает за инициацию объектов request
и
response
и вызов подходящего объекта реализации JSP-страницы.
По окончании процессинга, объект
response
получается контейнером для соединения с клиентом.
Детали соглашения/контракта между классом реализации JSP-страницы и JSP-контейнером
описаны в Главе JSP.8.
Трансляция JSP-страницы-источника в класс её реализации может произойти в любой
момент между начальной публикацией JSP-страницы в JSP-контейнер и получением и
процессингом запроса клиента для целевой JSP-страницы. В Разделе JSP.2.1.5
описывается выполнение фазы трансляции перед публикацией.
JSP-страница может отмечать обработку некоторых событий. В JSP 1.2 только события init и destroy могут быть описаны в JSP-странице.
Когда первый запрос направляется JSP-странице, метод
jspInit()
, если он имеется,
будет вызван для подготовки страницы.
Аналогично, JSP-контейнер может вызывать метод JSP jspDestroy()
для переделки ресурсов, используемых JSP-страницей, в любой момент, когда запрос
не обслуживается. Это такой же жизненный цикл, что и у сервлетов.
JSP-страница может быть откомпилирована в свой класс реализации, плюс
информация публикации в процессе создания (JSP-страница может также
компилироваться в процессе публикации).
Таким способом утилиты авторизации JSP-страниц и библиотеки тэгов JSP могут
использоваться для создания сервлетов. Преимущества этого подхода таковы:
Компиляция JSP-страницы в контексте web-приложения предоставляет разрешение
спецификаций относительных URL в директивы include
(и в другом месте),
ссылок на taglib
и акции времени трансляции, используемых в специальных акциях.
JSP-страница может также компилироваться во время публикации.
Когда класс реализации JSP-страницы зависит от поддержки классов (в дополнение к классам JSP 1.2 и Servlet 2.3), классы поддержки включаются в упакованный WAR-файл (как определено в спецификации Servlet 2.3) для обеспечения переносимости по JSP-контейнерам.
В Приложении JSP.A есть два примера упаковки JSP-страниц в WAR'ы:
В информации для публикации указаны необходимые поддерживающие классы и отображение между путём оригинального URL в JSP-страницу и URL для класса реализации этой JSP-страницы.
Раньше утилиты отладки не имели стандартного формата для передачи информации отображения исходного кода, позволяющей использовать отладчик одного производителя с JSP-контейнером другого. Спецификация с поддержкой отладки, преодолевшая эти ограничения, разрабатывается как JSR-045 процесса JCP 2.0 под названием “Debugging Support for Non-Java Languages/Поддержка Отладки для Не-Java-Языков”.
Детали можно найти по адресу
JSP-страница упаковывается в один или более файлов, часто - как web-приложение,
и направляется утилите типа JSP-контейнера, J2EE-контейнера или IDE. Полная JSP-страница
может содержаться в одном файле. В других случаях основной файл содержит другие
файлы, которые содержать полные JSP-страницы или включаемые фрагменты.
Утилиты обычно требуют отделения файлов JSP-страницы от других файлов.
В некоторых случаях утилиты также требуют отделения файлов верхнего уровня/top JSP
от включаемых фрагментов. Например, если фрагмент может не быть правильной JSP-страницей
и может не компилироваться соответствующим образом.
Определение типа файла также часто практикуется на уровне документации и
обслуживания, как должно быть уже известно тем, кто работает с соглашениями “.c”
и “.h” языка C.
Спецификация Servlet 2.3 использует расширение “.jsp” для обозначения JSP-страницы,
но не дифференцирует основные JSP-файлы и включаемые фрагменты.
Мы рекомендуем (но не обязываем), чтобы:
Приложение web это коллекция ресурсов, которые доступны по указанным URL.
Web-приложение состоит из следующих компонентов:
Web-приложения описаны более детально в спецификации Servlet 2.3.
Web-приложение содержит дескриптор публикации
web.xml, содержащий информация о JSP-страницах,
сервлетах и других ресурсах, используемых в этом web-приложении. Дескриптор
публикации детально описан в спецификации Servlet 2.3.
JSP 1.2 требует, чтобы эти ресурсы были неявно/косвенно ассоциированы с, и доступны через, уникальный экземпляр
ServletContext
, доступный как неявный объект приложения (Раздел JSP.2.8).
Приложение, которому принадлежит JSP-страница, отражается в объекте
application
и влияет на семантику следующих элементов:
include
(Раздел JSP.2.10.3).jsp:include
(Раздел JSP.4.4).jsp:forward
(Раздел JSP.4.5).JSP 1.2 поддерживает переносимую упаковку и публикацию/deployment web-приложений через спецификацию Servlet 2.3. Спецификация JavaServer Pages наследует от спецификации Servlet концепцию приложений, ServletContext'ы, Sessions/Сессии, Requests/Запросы и Responses/Ответы.
Элементы могут использовать спецификации относительных URL, называемые “URI-пути”
в спецификации Servlet 2.3. Эти пути описаны в
спецификации RFC 2396. Мы имеем в виду часть path данной спецификации, а не
части scheme или authority.
Некоторые примеры:
Путь относительно контекста это путь, начинающийся со знака “/”. Он
интерпретируется относительно приложения, к которому принадлежит JSP-страница,
то есть говорится, что её объект ServletContext
предоставляет базовый контекстный URL.
Путь относительно страницы это путь, не начинающийся со знака “/”. Он
интерпретируется как относительный к текущей JSP-странице или текущему JSP-файлу,
в зависимости от того, где путь используется:
для директивы include
(Раздел
JSP.2.10.3); когда путь используется в атрибуте файла - интерпретация
относительно JSP-файла;
для акции jsp:include
(Раздел JSP.4.4), когда путь используется атрибуте
страницы - интерпретация относительно JSP-страницы.
В обоих случаях текущая страница (или файл) обозначается некоторой частью пути,
начинающейся с “/”, который (путь) затем модифицируется новой спецификацией, производящей путь
с начальным “/”.
Новый путь интерпретируется через объект ServletContext
. См. точную информацию
об этой интерпретации в Разделе JSP.2.10.4.
Спецификация JSP универсально интерпретирует пути в контексте web-сервера, где JSP-страница
публикуется. Спецификация проходит через отображающую трансляцию. Семантика,
обрисованная здесь, применяется к фазе времени трансляции, а не к фазе времени запроса.
В этом разделе описаны базовые синтаксические правила JSP-страниц.
JSP-страница содержит элементы и шаблонные данные.
Элемент является экземпляром типа элемента, известного JSP-контейнеру.
Шаблонные данные это то, о чём JSP-танслятор ничего не знает.
Тип элемента описывает его синтаксис и семантику. Если элемент имеет атрибуты, тип описывает имена, верные типы атрибутов и их интерпретацию. Если элемент определяет объекты, семантика включает эти определяемые объекты и их типы.
Имеются элементы трёх типов: директивы, элементы скриптинга и акции.
Директивы предоставляют глобальную информацию, которая концептуально верна, независимо от специфики запроса, полученного JSP-страницей. Директивы предоставляют информацию для фазы трансляции.
Синтаксис элемента-директивы
<%@ директива...%>
Акции предоставляют информацию для фазы обработки запроса. Интерпретация
акции может, и часто так и бывает, зависеть от специфики запроса,
полученного JSP-страницей.
Акции могут быть стандартными, то есть
определёнными этой спецификацией, или
custom/специальными, то есть предоставленными через посредство механизма
развёртывания переносимых тэгов.
Элементы action
следуют синтаксису XML-элемента: они имеют начальный тэг, включающий имя
элемента, и могут иметь атрибуты, необязательное тело/body и соответствующий
конечный тэг, или они могут быть пустыми тэгами, возможно, с атрибутами:
<mytag attr1=”значение атрибута”...>body</mytag>
и
<mytag attr1=”значение атрибута”.../>
<mytag attr1=”значение атрибута” ...></mytag>
Элемент имеет тип элемента, описывающий имя его тэга, верные атрибуты и их семантику.
Мы обращаемся к типу по имени его тэга.
JSP-тэги чувствительны к регистру, как в XML и XHTML.
Акция может создавать объекты и делать их доступными элементам скриптинга через
специфические для скриптинга переменные.
Элементы Скриптинга являются связкой между шаблонным текстом и акциями.
Есть три типа элементов скриптинга:
declarations\объявления, scriptlets\скриптлеты и expressions\выражения.
Объявления имеют синтаксис
<%! ... %>
скриптлеты
<% ... %>
выражения
<%= ... %>
Элементы, имеющие разные начальный и конечный тэги (при наличии тела), обязаны
иметь начало и конец в одном файле. Стартовый тэг не может быть в одном файле,
когда конечный тэг находится в другом файле.
То же самое правило применяется к элементам с альтернативным синтаксисом.
Например, скриптлет имеет синтаксис
<% скриптлет %>
.
Открывающий <%
и закрывающий %>
символы обязаны находиться в одном
и том же физическом файле.
Язык скриптинга может также вводить ограничения на размещение начальных и
конечных тэгов для специфических конструкций скриптинга. Например, в
Главе 6
демонстрируется, как блоки языка Java не могут разделять начальный и конечный
тэг; см. детали в Разделе JSP.6.4.
Следуя спецификации XML, элемент, описанный с использованием пустого тэга, не
отличается от элемента. использующего начальный тэг, пустое тело и конечный тэг.
Вот примеры пустых тэгов:
<x:foo></x:foo>
<x:foo />
<x:foo/>
<x:foo><%-- любой комментарий --%></x:foo>
Далее - примеры непустых тэгов:
<foo> </foo>
<foo><%= выражение %></foo>
<foo><% скриптлет %></foo>
<foo><bar/></foo>
<foo><!-- комментарий --></foo>
Следуя спецификации XML, атрибуты всегда заключаются в кавычки. Одинарные или двойные кавычки могут использоваться для уменьшения необходимости ввода кавычек мнемониками; соглашения по кавычкам описаны в Разделе JSP.2.6. Есть два типа значений атрибутов: литералы и выражения времени запроса (Раздел JSP.2.13.1), но правила применения кавычек - одинаковы.
Имена акций обязаны следовать соглашению XML (т.е. обязаны быть NMTOKEN
, как указано
в спецификации XML 1.0). Имена атрибутов обязаны следовать соглашениям, описанным в спецификации JavaBeans.
Имена атрибутов, начинающиеся с jsp,
_jsp, java или sun зарезервированы данной спецификацией.
В HTML и XML пробел обычно не является значащим, но есть исключения.
Например, файл XML может начинаться символами
<?xml
, и,
если это так, ведущих пробельных символов не должно быть.
Данная спецификация следует поведению пробелов, определённому в спецификации XML.
Пробел в теле текста документа не является значащим, но сохраняется.
Далее идут два фрагмента JSP с ассоциированным выводом.
Обратите внимание, что директивы не генерируют никаких данных и применяются глобально к
JSP-странице.
№ Строки | Исходный Текст |
---|---|
1 | <?xml version=”1.0” ?> |
2 | <%@ page buffer=”8kb” %> |
3 | Здесь - остальная часть документа. |
Результат:
№ Строки | Текст на Выходе |
---|---|
1 | <?xml version=”1.0” ?> |
2 | |
3 | Здесь - остальная часть документа. |
Следующие две таблицы - другой пример ввода и вывода:
№ Строки | Исходный Текст |
---|---|
1 | <% response.setContentType(“....”); |
2 | что-нибудь... %><?xml version=”1.0” ?> |
3 | <%@ page buffer=”8kb” %> |
4 | Здесь - остальная часть документа. |
Результат:
№ Строки | Текст на Выходе |
---|---|
1 | <?xml version=”1.0” ?> |
2 | |
4 | Здесь - остальная часть документа. |
Ошибки могут появляться на этапах трансляции или запроса. В этом разделе описывается, как ошибки обрабатываются соответствующей реализацией.
Трансляция JSP-страницы-источника в соответствующий класс реализации JSP-страницы JSP-контейнером
может производиться в любой момент между начальной публикацией JSP-страницы в JSP-контейнер
и получением и обработкой запроса клиентом целевой JSP-страницы.
Если трансляция возникает до получения клиентского запроса целевой JSP-страницы,
обработка ошибок и уведомление зависят от реализации и не рассматриваются в
данной спецификации. Фатальные ошибки трансляции должны в результате приводить к
невозможности выполнения последующих клиентских запросов на трансляцию целевой
страницы с соответствующей спецификацией ошибки:
для протоколов HTTP будет возвращаться код ошибки 500 (Server Error/Ошибка Сервера).
В процессе обработки запросов клиентов ошибки могут возникать в теле класса
реализации JSP-страницы или в каком-либо другом коде (языка Java или других
языков программирования реализации), вызываемом из тела класса реализации JSP-страницы.
Возникающие ошибки этапа прогона обрабатываются в реализации страницы, используя
механизм исключений языка программирования Java для сообщения вызывающему(-им) о
нарушениях.
Обратите внимание, что это не зависит от языка программирования. Данная
спецификация требует, чтобы о необработанных ошибках, возникающих в среде языка
скриптинга, используемого реализацией JSP-контейнера, сообщалось классу
реализации JSP-страницы через механизм исключений языка
Java.
Эти исключения могут отлавливаться и обрабатываться (как необходимо) в теле класса реализации JSP-страницы.
Любые неотловленные исключения, вызываемые в теле класса реализации JSP-страницы,
приводят к перенаправлению клиентского запроса и неотловленного исключения по URL
errorPage
, специфицированному этой JSP-страницей (или выполнением действий по
умолчанию, если ничего не специфицировано).
Нарушающее java.lang.Throwable
, описывающее появляющуюся ошибку, хранится в экземпляре
javax.ServletRequest
клиентского запроса, использующего метод
setAttribute()
, использующего имя “javax.servlet.jsp.jspException”
.
Имена, начинающиеся с префиксов “java”
и “javax”
, зарезервированы различными
спецификациями платформы Java. Префикс “javax.servlet”
зарезервирован и используется спецификациями Servlet и JSP.
Если атрибут errorPage
директивы страницы именует URL, который ссылается на другую JSP и та JSP
сигнализирует, что на странице имеется ошибка (установкой атрибута
isErrorPage
директивы страницы в true
), тогда неявная переменная языка программирования
“exception” этой страницы инициализируется ссылкой Throwable
-нарушителя.
В JSP-странице есть два типа комментариев:
комментарии к самой JSP-странице, документирующие действия страницы, и
комментарии, предназначенные для вывода в генерируемом документе, направляемом клиенту.
Для генерации комментариев, появляющихся в потоке вывода response
к
запрашивающему клиенту, используется следующий синтаксис комментариев HTML и XML:
<!-- комментарии
... -->
Такие комментарии рассматриваются JSP-контейнером как неизменяемый шаблонный
текст. Если генерируемый комментарий должен содержать динамические данные, это
может быть сделано посредством такого синтаксиса:
<!-- комментарии
<%= выражение %> ещё комментарии ... -->
JSP-комментарий имеет форму:
<%-- что-либо, кроме закрывающих символов --%> ... --%>
Содержимое тела комментария полностью игнорируется. Комментарии используются для
документирования, а также для
“закомментирования” некоторой части JSP-страницы.
Обратите внимание, что JSP-комментарии не вкладываются.
Альтернативным способом размещения "комментария" на JSP-странице является
использование механизма комментария языка скриптинга. Например:
<% /** это комментарий ... **/ %>
В JSP-страницах применяются следующие соглашения по кавычкам:
Литерал %>
закавычивается %\>
Литерал <%
закавычивается <\%
Закавычивание выполняется независимо от того, является значение атрибута
литералом или выражением атрибута этапа запроса. Закавычивание может
использоваться в значениях атрибутов независимо от того, ограничены они
одинарными или двойными кавычками. Это выполняется только так, как описано ниже:
\’
. Это необходимо делать внутри значения атрибута,
ограниченного одинарными кавычками.\”
. Это необходимо делать внутри значения атрибута,
ограниченного двойными кавычками.\\
%>
записывается %\>
<%
записывается <\%
В следующей строке показаны неправильные значения атрибутов:
<mytags:tag value="<%= "hi!" %>"
/>
В следующей строке дан верный скриптлет, но с, возможно, неожиданным результатом. Результат будет “Joe said %\>”, а не “Joe said %>”:
<%= "Joe said %\\>" %>
В следующих строках - правильное закавычивание:
<%= "Joe said %/>" %>
<%= "Joe said %\>" %>
&