В этой главе рассматриваются возможности библиотеки тэгов по введению новых акций в JSP-страницу.
Сюда относятся поддержка переносимости, механизм проверки и поддержка утилит авторизации.
Здесь дан также концептуальный обзор библиотеки тэгов. Рассмотрен
Tag Library Descriptor/Дескриптор Библиотеки Тэгов и директива
taglib
. Детальное описание задействованных API даётся в
Главе JSP.10.
Библиотека Тэгов/Tag Library абстрагирует функциональность, используемую JSP-страницей, определяя специализированный (суб)язык, что делает возможным более естественно использовать эту функциональность в JSP-страницах.
Акции, вводимые Библиотекой Тэгов, могут использоваться авторами JSP-страниц явно
при авторизации - вручную, или неявно - через использование утилит авторизации.
Библиотеки Тэгов особенно применимы в утилитах авторизации, поскольку позволяют
сосредоточиться на главном, а параметры, указанные в экземпляре акции, сами
передают информацию утилите.
Акции, которые предоставляются из библиотеки тэгов, импортируются в JSP-страницу путём использования директивы
taglib
. Они доступны для использования на странице через префикс, заданный этой директивой.
Акции могут создавать новые объекты, которые могут
затем передаваться другим акциям или обрабатываться программно элементами скриптинга в JSP-странице.
Библиотеки тэгов являются переносимыми: они могут использоваться на любой JSP-странице
вне зависимости от того, какой язык скриптинга используется на этой странице.
Механизм развёртывания тэгов содержит информацию для:
Библиотека Тэгов описывается через Tag Library Descriptor ( TLD)/Дескриптор Библиотеки Тэгов, документ XML, рассматриваемый ниже.
Механизм расширения/развёртывания тэгов преследует следующие цели:
Процессинг/обработка JSP-страницы концептуально состоит из следующих этапов:
JSP-страницы могут авторизоваться с использованием двух различных синтаксисов: JSP- и XML-синтаксиса. Семантика и проверка страницы с синтаксисом JSP даётся со ссылкой на семантику и проверку эквивалентного документа с синтаксисом XML.
Первый этап - разбор JSP-страницы. Разбираемая страница разворачивается путём
выполнения директив include
. Информация из TLD используется на
данном этапе и включает идентификацию специальных тэгов так, что происходит
некоторая обработка директивами taglib
на JSP-странице.
Библиотеки Тэгов в XML-документе обрабатываются в порядке их появления на странице.
Каждая библиотека проверяется на наличие класса-проверщика/validator class. Если
он имеется, весь документ становится доступным её методу
validate()
как объект PageData
. Если JSP-контейнер поддерживает
jsp:id
, то эта информация может использоваться для предоставления информации оместонахождении ошибок.
Каждый специальный тэг в библиотеке проверяется на наличие класса
TagExtraInfo
. Если класс имеется, вызывается метод
isValid()
.
Далее документ XML обрабатывается для создания класса реализации JSP-страницы.
В ходе этого процесса могут создаваться переменные скриптинга.
Каждая
специальная акция будет предоставлять информацию о переменных, либо статично - в TLD,
либо более гибко - через использование метода getVariableInfo
класса TagExtraInfo
.
После того как класс реализации JSP-страницы ассоциирован с JSP-страницей, он будет рассматриваться как любой другой Servlet-класс: запросы будут направляться экземплярам этого класса. На этапе прогона экземпляры обработчиков будут создаваться, а их методы будут вызываться.
Семантика специфики специальной акции в библиотеке тэгов описывается через класс
обработчика тэга, который обычно инстанциируется на этапе прогона классом реализации JSP-страницы.
Если библиотека тэгов известна JSP-контейнеру
(Раздел JSP.7.3.9), это контейнер может использовать альтернативные реализации,
пока семантика сохраняется.
Обработчик тэга это класс Java, реализующий интерфейс Tag
, IterationTag
или
BodyTag
и являющийся представлением специальной акции на этапе прогона.
Класс реализации JSP-страницы инстанциирует класс обработчика тэга или
использует существующий объект обработчика тэга для каждой акции на JSP-странице.
Объект обработчика это Java-объект, реализующий интерфейс
javax.servlet.jsp.tagext.Tag
. Объект обработчика отвечает за взаимодействие JSP-страницы
и дополнительных серверных объектов/server-side objects.
Существуют три главных интерфейса: Tag
, IterationTag
и BodyTa
.
Tag
определяет базовые методы, необходимые всем обработчикам тэгов. Это методы setter
для инициализации обработчика тэга, в контексте данных и значений атрибутов акции, и методы
doStartTag()
и doEndTag()
.
IterationTag
является расширением
Tag
'а, предоставляя дополнительный метод doAfterBody()
, вызываемый для повторного обсчёта тела тэга.BodyTag
является расширением
IterationTag
'а с двумя новыми методами для обработчика тэга для манипулирования телом тэга:
setBodyContent()
передаёт буфер, объект BodyContent
, а
doInitBody()
даёт возможность обработки буфера до первого обсчёта тела в буфере.Использование интерфейсов упрощает создание обработчика тэга из существующего Java-объекта.
Имеются также два класса поддержки, которые могут использоваться в качестве базовых классов:
TagSupport
и BodyTagSupport
.
В JSP 1.2 имеется новый интерфейс, помогающий поддерживать целостность данных и
обслуживать ресурсы при возникновении исключительных ситуаций.
Интерфейс
TryCatchFinally
может добавляться в класс, реализующий любой интерфейс:
Tag
, IterationTag
или BodyTag
.
Библиотека тэгов может содержать классы, которые являются прослушивателями событий (см. спецификацию Servlet 2.3). Классы-прослушиватели перечисляются в дескрипторе библиотеки тэгов, и JSP-контейнер автоматически инстанциирует и регистрирует их. Контейнер нужен для размещения всех TLD-файлов (см. в Разделе JSP.7.3.1 детали об их идентификации), чтения их элементов-прослушивателей и рассмотрения прослушивателей событий как расширений этих же прослушивателей, перечисленных в web.xml. Порядок регистрации прослушивателей не определён, но они регистрируются до старта приложения.
В качестве примеров мы рассмотрим прототипы использования развёртывания тэгов, кратко остановившись на преимуществах этих механизмов.
Простейшая акция просто делает что-нибудь, возможно - с параметрами, для
модификации этого "что-нибудь" и улучшения использования.
Акция этого типа может быть реализована через обработчик тэга, который реализует
интерфейс Tag. Этот обработчик тэга должен использовать только метод
doStartTag()
, который вызывается при обнаружении начального/стартового тэга. Он
имеет доступ к атрибутам тэга и информации о статусе JSP-страницы. Эта
информация передаётся объекту
Tag через вызовы setter-метода, прежде чем будет вызван
doStartTag()
.
Поскольку часто встречаются простые акции с пустым телом, Tag Library
Descriptor может использоваться для указания на то, что данный тэг всегда предполагается как пустой.
Такая индикация позволяет лучше проверять ошибки на этапе трансляции и даёт код
более высокого качества в классе реализации JSP-страницы.
Другой набор простых акций требует, чтобы что-нибудь происходило, когда
обнаруживается начальный тэг и когда обнаруживается конечный тэг. Интерфейс Tag
может также использоваться для этих акций. Метод
doEndTag()
похож на метод
doStartTag()
, за исключением того, что он вызывается при обнаружении конечного
тэга акции. Результат вызова doEndTag
показывает, вычисляется ли оставшаяся часть страницы, или нет.
В некоторых случаях тело должно вызываться только при возникновении некоторого (возможно, сложного)
условия. И опять, этот тип акции поддерживается базовым интерфейсом
Tag
через использование return-значений метода doStartTag()
.
Для итераций необходим интерфейс IterationTag
. Метод
doAfterBody()
вызывается для определения необходимости повторного обсчёта тела.
Рассмотрим акцию, которая обсчитывает своё тело несколько раз, создавая поток
данных ответа. Для этого используется протокол IterationTag
.
Если результат повторной интерпретации будет в дальнейшем обрабатываться, по
каким-то соображениям, в том числе и просто может быть отброшен, то нам нужен
способ "отвлечь" вывод/output от повторных обсчётов.
Это выполняется путём создания объекта
BodyContent
и использования метода setBodyContent()
, который является частью интерфейса BodyTag
.
BodyTag
также предоставляет метод doInitBody()
, вызываемый после
setBodyContent()
и до первого обсчёта тела, что является удобным моментом для взаимодействия с телом/body.
Кооперирующиеся акции могут предлагать наилучший способ описания необходимой функциональности.
Например, одна акция может использоваться для описания информации, приводящей к
созданию серверного объекта, а другая может использовать этот объект где-либо
на этой странице. Эти акции могут кооперироваться явно через переменные
скриптинга: одна акция создаёт объект и даёт ему имя; другая ссылается на объект по имени.
Переменные скриптинга кратко обсуждаются далее.
Две акции могут также кооперироваться неявно. Гибкий и удобный механизм
кооперирования акций использует вложение структуры акций для описания области
видимости. В данной спецификации это поддерживается через предоставление
обработчика каждого тэга и обработчика тэга его родителя (если имеется) через
вызов метода setParent()
. Статический метод findAncestorWithClass
в
TagSupport
может затем использоваться для локализации обработчика тэга и, после
локализации, для выполнения операций в обработчике тэга.
Специальные акции могут создавать серверные объекты и делать их доступными
элементам скриптинга через создание или обновление переменных скриптинга.
Обработанные таким образом переменные являются частью семантики специальной
акции и находятся в зоне ответственности автора библиотеки тэгов.
Эта информация используется во время трансляции JSP-страницы и может быть
описана одним из двух способов: непосредственно в
TLD - для простых случаев, или через субклассы TagExtraInfo
.
Каждый механизм будет указывать имена и типы переменных скриптинга.
На этапе запроса обработчик тэга будет ассоциировать объекты с переменными
скриптинга через объект pageContext
.
Транслятор JSP-страницы отвечает за то, чтобы автоматически снабжать кодом,
необходимым для выполнения "синхронизации" между значениями pageObject
и переменными скриптинга.
Библиотека тэгов это коллекция акций, инкапсулирующая некоторую
функциональность, используемую в JSP-странице. Библиотека тэгов становиться
доступной JSP-странице через использование директивы
taglib
, которая идентифицирует эту библиотеку тэгов с помощью URI (Universal Resource Identifier/Универсальный
Идентификатор Ресурсов).
URI, идентифицирующий библиотеку тэгов, может быть любым верным URI, который
может использоваться для уникальной идентификации семантики библиотеки тэгов.
URI, идентифицирующий библиотеку тэгов, ассоциируется с файлом Tag Library
Description (TLD) и с классами обработчиков тэгов, как указано далее
в Разделе JSP.7.3.
Утилиты авторизацииJSP-страниц и JSP-контейнеры должны принимать библиотеку тэгов, упакованную в JAR-файл.
При поставке в JSP-контейнере применяются стандартные соглашения по JAR,
описанные в спецификации Servlet 2.3, включая
соглашения для зависимостей расширений.
Упакованные библиотеки тэгов обязаны иметь как минимум один файл дескриптора библиотеки тэгов.
Спецификация JSP 1.1 разрешала только один TLD, в META-INF/taglib.tld, а в
JSP 1.2 разрешены несколько библиотек тэгов. См. в Разделе JSP.7.3.1 об
идентификации TLD.
Библиотека тэгов содержит классы для инстанциации на этапе трансляции и классы
для инстанциации на этапе запроса. Первые содержат классы TagLibraryValidator
и
TagExtraInfo
. Вторые содержат классы обработчика тэгов и прослушивателя событий.
Применяются обычные соглашения по классам Java: как часть web-приложения они
обязаны находиться внутри либо JAR-файла в директории WEB-INF/lib, либо в директории WEB-INF/classes.
JAR, содержащий упакованные библиотеки тэгов, может быть сброшен в директорию WEB-INF/
lib, чтобы сделать его классы доступными на этапе запроса (а также на этапе
трансляции, см. Раздел JSP.7.3.7).
Отображение между URI и TLD объясняется далее.
Директива taglib
в JSP-страниц объявляет, что эта страница использует библиотеку тэгов,
уникально идентифицирует эту библиотеку через URI и ассоциирует префикс тэга с использованием акций библиотеки.
JSP-контейнер отображает URI, используемый в директиве taglib
, в Tag Library
Descriptor/Дескриптор Библиотеки Тэгов за два шага: сначала разрешает URI в путь
ресурса TLD, а затем получает TLD-объект из пути ресурса TLD.
Если JSP-контейнер не может локализовать путь ресурса TLD для данного URI,
должна происходить фатальная ошибка трансляции.
Аналогично, фатальной ошибкой трансляции является развёртывание/разрешение
значения атрибута uri
в два различных пути ресурса TLD.
Для директивы taglib
будет фатальной ошибкой, если она появится после акций,
использующих префикс, вводимый ею.
Дескриптор Библиотеки Тэгов/Tag Library Descriptor (TLD) это XML-документ,
который описывает библиотеку тэгов. TLD библиотеки тэгов используется JSP-контейнером
для интерпретации страниц, которые содержат директивы
taglib
, ссылающиеся на эту библиотеку тэгов. TLD используется также утилитами
авторизации/создания JSP-страниц, которые будут генерировать JSP-страницы,
использующие библиотеку, и авторами, делающими то же самое вручную.
TLD содержит документацию о библиотеке в целом и о каждом из её тэгов,
информацию о версии JSP-контейнера и о библиотеке и информацию о каждой акции, определённой в этой библиотеке тэгов.
TLD может именовать класс TagLibraryValidator
, который может проверять
соответствие JSP-страницы набору ограничений, ожидаемых этой библиотекой тэгов.
Каждой акции в библиотеке присваивается имя, класс её обработчика тэга,
информация о переменных скриптинга, создаваемых этой акцией, и информация об
атрибутах акции. Информация о переменных скриптинга может быть задана
непосредственно в TLD или через класс TagExtraInfo
.
Каждый верный атрибут содержит указания на то, является ли он мандатным, может
ли он принимать выражения времени запроса, и дополнительную информацию.
Файл TLD используется для предоставления информации о библиотеке тэгов. Он может
быть прочитан утилитами без инстанциации объектов или классов загрузчика.
Наш подход соответствует соглашениям в других технологиях J2EE.
ОТД для дескриптора библиотеки тэгов организовано так, что нужные элементы имеют
необязательный атрибут ID. Этот атрибут может использоваться другими
документами, типа документации продавца, для предоставления аннотаций по информации TLD.
Файл дескриптора библиотеки тэгов (ДБТ) именуется с использованием расширения ".tld", которое указывает, что это файл ДБТ.
Если размещены внутри файла JAR,
файлы ДБТ обязаны находиться в директории META-INF или в её субдиректории.
При размещении непосредственно в web-приложении файлы ДБТ обязаны всегда
находиться в директории WEB-INF или в одной из её субдиректорий.
Документ ОТД для ДБТ это
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd".
URI в директиве taglib
отображается в контексте относительного пути (это обсуждается в
Разделе JSP.2.2.1).
Контекст относительного пути это URL без указания компонентов - протокола и хоста, начинающийся с "/"
и называемый путь ресурса TLD.
Путь ресурса TLD интерпретируется относительно корневой директории web-приложения
и должен указывать непосредственно на TLD-файл или на JAR-файл, содержащий TLD-файл в META-INF/taglib.tld.
Если путь ресурса TLD - не один из этих вариантов, будет возникать фатальная ошибка трансляции.
URI, описывающий библиотеку тэгов, отображается в путь ресурса TLD через отображение taglib,
и в интерпретацию крайнего варианта, которая используется, если отображение не содержит URI.
Отображение taglib
строится из явного отображения taglib
в web.xml
(описано в Разделе JSP.7.3.3), которое расширяется неявными вхождениями,
выведенными из упакованных библиотек тэгов в
web-приложение (описано в Разделе JSP.7.3.4),
и неявными вхождениями, известными JSP-контейнеру.
Интерпретация варианта "на крайний случай" нацелена на случайное использование
своего механизма, как в цикле разработки Web-Приложения: тогда URI
интерпретируется как непосредственный путь к TLD (см. Раздел JSP.7.3.6.2).
taglib
в web.xmlФайл web.xml может содержать явное отображение taglib
между путями ресурсов URI и TLD,
описанное с использованием элементов taglib
Дескриптора Публикации Web-Приложения в файле
WEB-INF/web.xml, как описано в спецификации Servlet 2.3 и в
http://java.sun.com/j2ee/dtds/web-app_2_3.dtd.
Элемент taglib
содержит два субэлемента:
taglib-uri
и taglib-location
.
<taglib>
taglib
является субэлементом web-app
:
<!ELEMENT
web-app .... taglib* .... >
Элемент taglib
предоставляет информацию о библиотеке тэгов, которая используется JSP-страницей
внутри Web-Приложения.
Элемент taglib
содержит два субэлемента и один атрибут:
<!ELEMENT taglib
( taglib-uri, taglib-location )>
<!ATTLIST taglib id ID #IMPLIED>
<taglib-uri>
Элемент taglib-uri
описывает URI, идентифицирующий библиотеку тэгов, используемую в web-приложении.
<!ELEMENT taglib-uri (#PCDATA)>
PCDATA ::= спецификация URI.
Телом элемента taglib-uri
может быть абсолютный или относительный URI, как указано в
Разделе
JSP.2.2.1.
В web.xml не должно быть входов с тем же значением taglib-uri
.
<taglib-location>
содержит место размещения (в качестве ресурса) Файла Дескриптора
Библиотеки Тэгов для данной библиотеки тэгов.
taglib-location
<!ELEMENT taglib-location
(#PCDATA)>
PCDATA ::= размещение ресурса (как указано в Разделе JSP.2.2.1); где можно найти файл TLD.
Отображение taglib
, описанное в web.xml, расширяется за счёт новых вхождений,
извлекаемых из файлов TLD Web-Приложения.
Новые вхождения обсчитываются так:
<uri>
,
создаётся новый элемент <taglib>
с субэлементом
<taglib-uri>
, значением которого является значение элемента
<uri>
, и с субэлементом <taglib-location>
, указывающим на TLD-файл.<taglib>
содержит разные <taglib-uri>
для каждого отображения taglib
, он добавляется.
Этот механизм предоставляет автоматическое отображение URI в TLD, а также
поддержку нескольких TLD в одном JAR-пакете.
Обратите внимание, что эта функциональность не требует явного именования места
размещения TLD-файла, которого мог бы потребовать механизм типа протокола
jar:.
Заметьте также, что этот механизм не добавляет дублирующие вхождения.
Контейнер также может добавлять дополнительные вхождения к отображению taglib
.
Как и в предыдущем случае, входы добавляются только для тех URI, которые не
представлены в отображении. Концептуально эти вхождения соответствуют TLD,
описывающему эти библиотеки тэгов.
Эти неявные вхождения отображения соответствуют библиотекам, которые известны
контейнеру, который отвечает за предоставление их реализации, либо через
обработчики тэгов, либо через механизм, описанный в Разделе JSP.7.3.9.
Путь ресурса TLD может быть определён из атрибута uri
директивы
taglib
, как показано ниже. В последующем разъяснении "абсолютным URI" называется
такой, который начинается с названия протокола и имени хоста,
а "относительный URI" даётся так, как указано в Разделе
2.5.2, т.е. без протокола и имени хоста.
Все шаги описаны так, будто они выполнялись, но реализация может использовать
различные стратегии для получения того же результата.
Карта taglib
, генерированная в Разделах JSP.7.3.3,
JSP.7.3.4 и JSP.7.3.5, может
содержать одно или более вхождений
<taglib></taglib>
. Каждое такое вхождение идентифицируется по
TAGLIB_URI
, который является значением субэлемента <taglib-uri>
.
Этот TAGLIB_URI
может быть абсолютным URI, либо относительным URI, который начинается
(или не начинается) с "/".
Каждое вхождение определяет также TAGLIB_LOCATION
следующим образом:
<taglib-location>
это относительный URI, начинающийся с "/", то
TAGLIB_LOCATION
является этим URI.<taglib-location>
это относительный URI, не начинающийся с "/", то
TAGLIB_LOCATION
является разрешением этого URI относительно
/WEB-INF/web.xml (результатом этого разрешения является относительный URI, начинающийся с "/").
Здесь показано, как разрешить директиву taglib
для вычисления пути ресурса TLD
на базе значения атрибута uri
директивы taglib
.
uri
является ABS_URI
,
абсолютным URI. Идёт поиск в карте taglib
вхождения, чей TAGLIB_URI
является
ABS_URI
.
Если он найден, соответствующее TAGLIB_LOCATION
является путём ресурса TLD. Если он не найден,
возникает ошибка трансляции.uri
является ROOT_REL_URI
,
относительным URI, начинающимся с "/".
Идёт поиск в карте taglib
вхождения, чей
TAGLIB_URI
является ROOT_REL_URI
.
Если он найден, соответствующее
TAGLIB_LOCATION
является путём ресурса TLD. Если он не найден, ROOT_REL_URI
является путём ресурса TLD.uri
является
NOROOT_REL_URI
,
относительным URI, не начинающимся с "/". Идёт поиск в карте taglib
вхождения,
чей TAGLIB_URI
является NOROOT_REL_URI
.
Если он найден, соответствующее
TAGLIB_LOCATION
является путём ресурса TLD. Если он не найден,
NOROOT_REL_URI
разрешается относительно текущей JSP-страницы, где появилась
директива; это значение (по определению, это спецификация относительного URI,
начинающегося с "/") является путём ресурса TLD.Явное отображение web.xml предоставляет явное описание библиотек тэгов, используемых в web-приложении.
Неявное отображение из TLDs означает, что JAR-файл, реализующий библиотеку
тэгов, может быть раскрыт и использован непосредственно через его постоянные URI.
Использование относительного URI
в карте taglib
даёт возможность задания очень кратких имён в директиве
taglib
. Например, если карта:
<taglib>
<taglib-uri>/myPRlibrary</taglib-uri>
<taglib-location>/WEB-INF/tlds/PRlibrary_1_4.tld</taglib-location>
</taglib>
тогда она может использоваться как:
<%@ taglib uri="/myPRlibrary"
prefix="x" %>
Наконец, правило отката/fallback (запасной вариант) позволяет директиве
taglib
ссылаться непосредственно к
TLD.
Это чрезвычайно хорошо подходит для ускоренной разработки в ущерб гибкости и
экономии.
Например, в предыдущем случае оно делает возможным:
<%@ taglib
uri="/WEB-INF/tlds/PRlibrary_1_4.tld" prefix="x" %>
Набор классов, доступных во время трансляции, - тот же, что и для времени
прогона/runtime: классы основной платформы Java, в JSP-контейнере и в файлах
классов в WEB-INF/classes, в JAR-файлах в
WEB-INF/lib и, косвенно, классы, обозначенные через использование атрибута class-path
в файле-манифесте META-INF/MANIFEST этих JAR-файлов.
Как часть процесса ассемблирования web-приложения, Application Assembler будет
создавать директорию
WEB-INF/ с соответствующими субдиректориями
lib/
и
classes/,
размещать JSP-страницы, Servlet-классы,
вспомогательные классы и библиотеки классов в соответствующих местах и создаёт
файл
WEB-INF/web.xml, который связывает всё это воедино.
Библиотеки тэгов, полученные в стандартном формате JAR, могут быть помещены
непосредственно в
WEB-INF/lib.
Это автоматически добавляет все TLDs из JAR-файла, делая их URI их элементами <uri>
,
видимыми отображению URI
в TLD.
Ассемблер может создавать вхождения taglib
в
web.xml для каждой из библиотек, которые им используются.
Частью ассемблирования (и позже - публикации) может быть создание и/или
изменение информации, специализирующей библиотеку тэгов; см.
Раздел JSP.7.6.3.
JSP-контейнер может "знать" некоторые URI и может предоставлять альтернативные
реализации для библиотек тэгов, описанных этими URI, но пользователь обязан
видеть поведение как таковое, описанное описанием требуемой, переносимой
библиотеки тэгов, указанной в URI.
JSP-контейнер обязан всегда использовать отображение, специфицированное для URI,
в дескрипторе публикации
web.xml, если он имеется.
Если публикатор хочет использовать платформозависимую реализацию хорошо
известного URI, отображение такого
URI должно быть удалено во время публикации.
В этом разделе описано ОТД (Определение Типа Данных), для JSP версии 1.2, Дескриптора Библиотеки Тэгов/Tag Library Descriptor. Версия JSP 1.2 содержит информацию, дополнившую версию JSP 1.1, а также некоторые изменения в именах элементов, сделанные для улучшения совместимости с другими спецификациями. Формат TLD в 1.1 обязан приниматься контейнерами JSP 1.2.
<!NOTATION
WEB-JSPTAGLIB.1_2 PUBLIC "-//Sun Microsystems, Inc.//DTD
JSP Tag Library 1.2//EN">
<taglib>
Элемент taglib
это корень/root документа.
taglib
имеет два атрибута.
<!ATTLIST
taglib
id
ID
#IMPLIED
xmlns
CDATA
#FIXED
"http://java.sun.com/JSP/TagLibraryDescriptor"
>
Элемент taglib
имеет также различные субэлементы, которые определяют:
tlib-version
|
версию реализации библиотеки тэгов |
jsp-version
|
мандатную версию спецификации JSP, от которой зависит библиотека тэгов |
short-name
|
простое короткое имя по умолчанию, которое
может использоваться утилитой авторизации JSP-страниц
для создания имён с мнемоническими значениями; например, it может
использоваться как предпочтительное значение префикса в директивах taglib
|
uri
|
URI, уникально идентифицирующий эту taglib
|
display-name
|
элемент display-name , содержащий краткое имя,
которое предназначается для отображения утилитами |
small-icon
|
необязательная маленькая иконка, которая может использоваться утилитами |
large-icon
|
необязательная большая иконка, которая может использоваться утилитами |
description
|
строка, описывающая "use/использование" этой taglib
|
validator
|
необязательная информация класса TagLibraryValidator
|
listener
|
необязательная спецификация прослушивателя событий |
<!ELEMENT taglib
(tlib-version, jsp-version, short-name, uri?, display-name?, small-icon?, large-icon? description?, validator?, listener*, tag+)>
<tlib-version>
Описывает версию (номер) библиотеки тэгов.
Синтаксис:
<!ELEMENT
tlib-version (#PCDATA)>
#PCDATA ::= [0-9]*{ "."[0-9] }0..3
<jsp-version>
Описывает версию JSP-спецификации (номер), наличие которой необходимо данной
библиотеке тэгов для работы. Этот элемент является мандатным/обязательным.
Синтаксис:
<!ELEMENT
jsp-version (#PCDATA)>
#PCDATA ::= [0-9]*{ "."[0-9] }0..3.
<short-name>
Определяет простое краткое имя, которое может использоваться утилитами
авторизации JSP-страниц для создания имён с мнемоническим значением; например, it
может использоваться как предпочтительное значение префикса в директивах taglib
и/или для создания префиксов для ID'ов. Не используйте
пробелы и не начинайте с цифры и символа подчёркивания.
Синтаксис:
<!ELEMENT
short-name (#PCDATA)>
#PCDATA ::= NMTOKEN
<uri>
Определяет публичный URI, уникально идентифицирующий данную версию библиотеки тэгов.
<!ELEMENT uri
(#PCDATA)>
<description>
Определяет произвольную текстовую строку, описывающую библиотеку тэгов, переменную, атрибут или проверщик.
<!ELEMENT description (#PCDATA)>
<validator>
Определяет необязательный TagLibraryValidator
, который может использоваться для проверки возможности
использования JSP-страницей этой библиотеки тэгов. Проверщик может иметь некоторые необязательные параметры инициализации.
может иметь несколько субэлементов, определяющих:
validator
validator-class
|
класс, реализующий
javax.servlet.jsp.tagext.TagLibraryValidator
|
init-param
|
необязательные параметры инициализации |
description
|
необязательное описание проверщика |
Синтаксис элемента таков:
<!ELEMENT
validator (validator-class, init-param*, description?)>
<validator-class>
Определяет класс необязательного TagLibraryValidator
'а.
<!ELEMENT
validator-class (#PCDATA)>
<init-param>
Определяет параметр инициализации.
init-param
может иметь несколько субэлементов, определяющих:
param-name
|
имя параметра |
param-value
|
значение параметра |
description
|
необязательное описание параметра |
Синтаксис элемента:
<!ELEMENT
init-param (param-value, param-value, description?)>
<param-name>
Имя параметра.
<!ELEMENT
param-name (#PCDATA)>
<param-value>
Значение параметра.
<!ELEMENT
param-value (#PCDATA)>
<listener>
Определяет необязательный объект прослушивателя событий, инстанциируемый и регистрируемый автоматически.
<!ELEMENT
listener (listener-class)>
<listener-class>
Элемент listener-class
объявляет класс в приложении, который обязан быть
зарегистрирован как компонент прослушивателя web-приложения.
См. детали в спецификации Servlet 2.3.
<!ELEMENT
listener-class (#PCDATA)>
<tag>
определяет акцию в данной библиотеке тэгов.
tag
Обычно для описания семантики специальной акции, которая просматривается другими
специальными акциями, используется класс реализации обработчика тэга в элементе
tag-class
. Однако элемент description
также может использоваться для указания типа, ограничивающего затем
эти операции. Типом может быть void или подтип класса реализации обработчика
тэга. Эта информация может использоваться специализированным контейнером для
специфических хорошо известных библиотек тэгов; см. Раздел JSP.7.3.9.
Элемент tag
имеет один атрибут:
<!ATTLIST tag
id ID #IMPLIED>
может иметь несколько субэлементов, определяющих:
tag
name
|
уникальное имя акции |
tag-class
|
класс обработчика тэга, реализующий
javax.servlet.jsp.tagext.Tag
|
tei-class
|
необязательный подкласс
javax.servlet.jsp.tagext.TagExtraInfo
|
body-content
|
тип содержимого тела |
display-name
|
краткое имя, предназначенное для отображения утилитами |
small-icon
|
необязательная маленькая иконка, которая может использоваться утилитами |
large-icon
|
необязательная большая иконка, которая может использоваться утилитами |
description
|
необязательная специфическая информация тэга |
variable
|
необязательная информация переменной скриптинга |
attribute
|
все атрибуты этой акции |
example
|
необязательный пример использования этого тэга |
Синтаксис элемента:
<!ELEMENT tag
(name, tag-class, tei-class?, body-content?, display-name?, small-icon?, large-icon?, description?, variable*, attribute*, example?)>
<tag-class>
Определяет класс реализации для этой специальной акции. Класс обязан
реализовывать интерфейс
javax.serlvet.jsp.tagext.Tag
. Этот элемент необходим.
Синтаксис:
<!ELEMENT
tag-class (#PCDATA)>
#PCDATA ::= полное квалифицированное имя Java-класса
<tei-class>
Определяет субкласс javax.servlet.jsp.tagext.TagExtraInfo
для данного тэга. Это необязательный
элемент.
Синтаксис:
<!ELEMENT
tei-class (#PCDATA)>
#PCDATA ::= полное квалифицированное имя Java-класса
<body-content>
Предоставляет подсказку о содержимом тела данной акции. В первую очередь
предназначен для использования утилитами компоновки/создания страниц.
Имеются три специфицированных на данный момент значения:
tagdependent
|
Тело акции передаётся без изменений для
интерпретации самим обработчиком тэга и написано большей частью на другом "language" ,
например, встроенные операторы SQL. Тело акции может быть пустым.
Никакое закавычивание не выполняется. |
JSP
|
Тело акции содержит элементы, использующие синтаксис JSP. Тело акции может быть пустым. |
empty
|
Тело акции обязано быть пустым. |
Значение по умолчанию - "JSP".
Синтаксис:
<!ELEMENT
body-content (#PCDATA)>
#PCDATA ::= tagdependent | JSP | empty.
Значения зависят от регистра.
<display-name>
Элементы display-name
содержат краткое имя, которое предназначено для
отображения утилитами.
Синтаксис:
<!ELEMENT
display-name (#PCDATA)>
<large-icon>
Элемент large-icon
содержит имя файла, содержащего большое (32 x 32)
изображение-иконку. Имя файла это путь в библиотеке тэгов относительно
размещения TLD. Изображение обязано быть в формате JPEG или GIF, а имя файла
обязано заканчиваться суффиксом
".jpg" или ".gif", соответственно. Эта иконка может
использоваться утилитами.
Синтаксис:
<!ELEMENT
large-icon (#PCDATA)>
<small-icon>
Элемент small-icon
содержит имя файла, содержащего маленькое (16 x 16)
изображение-иконку. Имя файла это путь в библиотеке тэгов относительно
размещения TLD. Изображение обязано быть в формате JPEG или GIF, а имя файла
обязано заканчиваться суффиксом
".jpg" или ".gif", соответственно. Эта иконка может
использоваться утилитами.
Синтаксис:
<!ELEMENT
small-icon (#PCDATA)>
<variable>
Предоставляет информацию о переменных скриптинга, определённых этим тэгом. Для тэга будет ошибкой
(времени трансляции), если он имеет один или более субэлементов-переменных, имеющих класс
TagExtraInfo
, который возвращает ненулевой объект.
Субэлементы-переменные имеют форму:
name-given
|
постоянное/константное имя переменной |
name-from-attribute
|
имя атрибута, чьё значение
(на этапе трансляции) даст имя переменной. Необходимо наличие одного из субэлементов:
name-given или name-from-attribute
|
variable-class
|
имя класса переменной. По умолчанию java.lang.String
|
declare
|
объявлена переменная или нет. По умолчанию
true
|
scope
|
область видимости определённой переменной
скриптинга. По умолчанию NESTED
|
description
|
необязательное описание переменной |
Синтаксис:
<!ELEMENT
variable
((name-given | name-from-attribute), variable-class?, declare?, scope?, description?)>
<name-given>
Имя переменной скриптинга. Необходимо наличие name-given
или name-from-attribute
.
Синтаксис:
<!ELEMENT
name-given (#PCDATA)>
<name-from-attribute>
Имя атрибута, чьё значение (на этапе трансляции) даст имя переменной. Необходимо наличие одного из
субэлементов: name-given
или name-from-attribute
.
Синтаксис:
<!ELEMENT
name-from-attribute (#PCDATA)>
<variable-class>
Необязательное имя класса переменной скриптинга. По умолчанию java.lang.String
.
Синтаксис:
<!ELEMENT
class (#PCDATA)>
<declare>
Объявлена переменная скриптинга или нет. См.
TagExtraInfo
. Это элемент необязателен, и установлен по умолчанию в "true"
.
Синтаксис:
<!ELEMENT
declare #PCDATA)>
#PCDATA ::= true | false | yes | no
<scope>
Область видимости переменной скриптинга. См. TagExtraInfo
. Это элемент
необязателен, и установлен по умолчанию в "NESTED"
.
Синтаксис:
<!ELEMENT scope
#PCDATA)>
#PCDATA ::= NESTED | AT_BEGIN | AT_END
<attribute>
Предоставляет информацию об атрибуте данной акции. Atribute
определяет атрибут id
для внешнего связывания.
<!ATTLIST
attribute id ID#IMPLIED>
Субэлементы attribute
'а имеют форму:
name
|
имя атрибута (необходим) |
required
|
необходимо или не обязательно наличие атрибута (по выбору) |
rtexprvalue
|
может ли значение атрибута динамически вычисляться во время прогона выражением скриптлета (по выбору) |
type
|
тип значения атрибута (по выбору) |
description
|
необязательное описание атрибута |
Синтаксис:
<!ELEMENT
attribute (name, required?,rtexprvalue?, type?, description?)>
<name>
Определяет каноническое имя определяемого тэга или атрибута.
Синтаксис:
<!ELEMENT name (#PCDATA)>
#PCDATA ::= NMTOKEN
<required>
Определяет, является содержащий вложение/nesting атрибут
required/необходимым или optional/"по выбору".
Синтаксис:
<!ELEMENT
required (#PCDATA)>
#PCDATA ::= true | false | yes | no
Если отсутствует, то по умолчанию "false"
, т.е. это атрибут optional.
<rtexprvalue>
Определяет, может ли содержащий (имеющий вложенные атрибуты) атрибут иметь
выражения скриптлета в качестве значения, т.е. может ли значение атрибута
динамически вычисляться на этапе запроса, что противоположно статическому
значению, определяемому на этапе трансляции.
Синтаксис:
<!ELEMENT
rtexprvalue (#PCDATA)>
#PCDATA ::= true | false | yes | no
Если отсутствует, по умолчанию - "false"
, т.е. атрибут имеет статическое/static значение.
<type>
Определяет тип Java значения атрибута. Для литеральных значений
(rtexprvalue = false
)
тип всегда - java.lang.String
.
Если rtexprvalue
установлен в true
,
тогда type
определяет тип возвращаемого значения, ожидаемый от любого выражения
скриптлета, специфицированного как значение этого атрибута.
Значение данного атрибута должно совпадать со значением свойства основного компонента JavaBean.
Синтаксис:
<!ELEMENT type
(#PCDATA)>
#PCDATA ::= полное квалифицированное имя Java-класса - тип результата
Пример:
<type> java.lang.Object </type>
<example>
Содержимое этого элемента предназначается в качестве примера использования тэга.
Этот элемент не интерпретируется JSP-контейнером и не воздействует на семантику тэга.
<!ELEMENT example (#PCDATA)>
Есть несколько причин, почему структура JSP-страницы должна соответствовать некоторым правилам проверки:
Проверка может выполняться на этапе трансляции или на этапе запроса. Обычно проверка на этапе трансляции даёт больше информации, и спецификация JSP 1.2 предоставляет очень гибкий механизм проверки на этапе трансляции.
Определённая проверка на этапе трансляции проводится в Tag Library Descriptor (TLD).
В некоторых случаях для предоставления поддержки этой информации необходимо наличие класса
TagExtraInfo
.
Tag Library Descriptor содержит базовую синтаксическую информацию. Атрибуты
описываются с включением его имени, являются ли они необязательными или
мандатными и принимают ли они выражения времени запроса. Кроме того, элемент
bodycontent
может использоваться для указания на то, что акция обязаны быть пустой.
Все ограничения, описанные в TLD, обязаны форсироваться. Автор библиотеки тэгов может принять как данное, что
экземпляр обработчика тэга соответствует акции, которая удовлетворяет всем
ограничениям, указанным в TLD.
Класс TagLibraryValidator
может быть указан в TLD библиотеки тэгов для запроса проверки этой JSP-страницы.
XML-просмотр JSP-страницы экспонируется через класс
PageData, и класс validator/проверщика может выполнять любую проверку, которую
автор библиотеки тэгов сочтёт необходимой.
JSP-контейнер может по выбору уникально идентифицировать все XML-элементы в
XML-просмотре JSP-страницы через атрибут
jsp:id
. этот атрибут может использоваться для предоставления большей информации о местонахождении ошибки.
механизм класса проверщика является новым для спецификации JSP 1.2.
может быть передан некоторым параметрам инициализации в TLD.
Это облегчает многократное использование классов проверщика. Мы ожидаем, что validator-классы
будут написаны на базе различных механизмов схемы XML
(DTDs, XSchema, Relaxx, других). Стандартные классы проверщика могут быть внедрены в последующих версиях
спецификации JSP, если когда-нибудь появится полный стандарт схемы.
TagLibraryValidator
TagExtraInfo
Дополнительная проверка на этапе трансляции может выполняться путём
использования метода isValid
класса TagExtraInfo
. Метод
isValid
вызывается на этапе трансляции и передаётся в экземпляр
Tag Dat в качестве его аргумента.
Механизм isValid
был первоначальным механизмом проверки, введённым в
JSP 1.1 вместе с механизмами Расширения Тэгов. Библиотеки тэгов, созданные для запуска в контейнерах JSP 1.2, должны
использовать механизм класса проверщика.
В некоторых случаях может динамически выполняться дополнительная проверка на
этапе запроса в методах обработчиков тэгов. Если обнаруживается ошибка, вызывается экземпляр
JspException
. Если ошибка не отловлена, этот объект вызовет механизм errorpage спецификации JSP.
Этот раздел не является нормативным, хотя отражает практику разработки.
Мы предлагаем придерживаться следующего стиля введения неявных объектов:
defineObjects
определяет необходимые объекты.JSP-страница может сделать эти объекты доступными так:
<%@ tablig
prefix="me" uri="......" %>
<me:defineObjects />
.... начинается использование объектов ....
Этот подход имеет то преимущество, что не требует новых механизмов и установления слишком явной зависимости.
В некоторых случаях доступность этих объектов может зависеть от реализации.
Например, они могут предоставлять доступ к некоторой функциональности, которая имеется
только в определённой реализации. Это может быть выполнено через проверку
классом расширения тэга на этапе прогона на предмет наличия некоторых свойств
данной реализации и вызова ошибки этапа прогона (это, конечно, не делает страницу ближе к J2EE).
Этот механизм, вместе с доступом к информации метаданных, позволяет продвигать новинки наряду со стандартом.
Примечание: если новая возможность добавлена к спецификации
JSP и продавец также предоставляет эту возможность через свой специфический
механизм, стандартным механизмом, как указано в спецификации JSP, будет "win".
Это значит, что механизмы, специфичные для продавца, могут постепенно перейти в
спецификацию, если докажут свою пригодность.
Если продавец хочет ассоциировать некоторую информацию, не описанную в текущей версии TLD, с некоторой библиотекой тэгов, он может сделать это, вставив информацию в контролируемый им документ, включив этот документ в часть WEB-INF JAR-файла там, где находится Tab Library/Библиотека Тэгов, и используя стандартные механизмы Servlet 2.2 для доступа к этой информации. Продавец может теперь использовать ID-механизмы для ссылки на элемент внутри TLD.
Библиотека тэгов может быть специализирована в ходе ассемблирования и публикации. Например,
библиотека тэгов, предоставляющая доступ к базам данных, может быть
специализирована информацией логина и пароля.
В web.xml в спецификации Servlet 2.2 нет подходящего места для специализированной
информации. Стандартизованный механизм, возможно, станет частью последующей
JSP-спцификации, но пока советуем авторам библиотек тэгов размещать такую
информацию в хорошо известном месте какого-нибудь ресурса в части
WEB-INF/ Web-Приложения давать к ней доступ через вызов getResource()
в ServletContext
.