Spec-Zone .ru
спецификации, руководства, описания, API


Пакет javax.servlet.jsp.tagext

Классы и интерфейсы для определения Библиотек Тега Страниц JavaServer.

См.:
          Описание

Сводка интерфейса
BodyTag Интерфейс BodyTag расширяет IterationTag, определяя дополнительные методы, которые позволяют обработчику тега управлять контентом оценки его тела.
DynamicAttributes Для тега, чтобы объявить, что это принимает динамические атрибуты, это должно реализовать этот интерфейс.
IterationTag Интерфейс IterationTag расширяет Тег, определяя один дополнительный метод, который управляет переоценкой его тела.
JspIdConsumer Этот интерфейс указывает к контейнеру, что обработчик тега хочет быть предоставленным компилятор сгенерированному ID.
JspTag Служит основным class для Тега и SimpleTag.
SimpleTag Интерфейс для того, чтобы определить Простые Обработчики Тега.
Тег Интерфейс классического обработчика тега, который не хочет управлять его телом.
TryCatchFinally Вспомогательный интерфейс Тега, IterationTag или BodyTag тегирует обработчик, который хочет дополнительные рычаги для того, чтобы управлять ресурсами.
 

Сводка класса
BodyContent Инкапсуляция оценки тела действия, таким образом, это доступно обработчику тега.
BodyTagSupport Основной class для того, чтобы определить реализацию обработчиков тега BodyTag.
FunctionInfo Информация для функции в Библиотеке Тега.
JspFragment Инкапсулирует часть кода JSP в объекте, который может быть вызван так много раз как необходимый.
PageData Разовая преобразованием информация на странице JSP.
SimpleTagSupport Основной class для того, чтобы определить реализацию обработчиков тега SimpleTag.
TagAdapter Обертки любой SimpleTag и представляют это использующий интерфейс Тега.
TagAttributeInfo Информация об атрибутах Тега, доступного во время преобразования.
TagData (Разовый преобразованием только) приписывают/оценивают информацию для экземпляра тега.
TagExtraInfo Дополнительный class, обеспеченный автором библиотеки тега, чтобы описать дополнительную разовую преобразованием информацию, не описанную в TLD.
TagFileInfo Информация о теге для файла тега в Библиотеке Тега; Этот class инстанцируют от файла Дескриптора Библиотеки Тега (TLD) и доступен только во время преобразования.
TagInfo Информация о теге для тега в Библиотеке Тега; Этот class инстанцируют от файла Дескриптора Библиотеки Тега (TLD) и доступен только во время преобразования.
TagLibraryInfo Разовая преобразованием информация, связанная с taglib направляющим, и ее базовый файл TLD.
TagLibraryValidator Разовый преобразованием блок проверки допустимости class для страницы JSP.
TagSupport Основной class для того, чтобы определить новые обработчики тега, реализовывая Тег.
TagVariableInfo Переменная информация для тега в Библиотеке Тега; Этот class инстанцируют от файла Дескриптора Библиотеки Тега (TLD) и доступен только во время преобразования.
ValidationMessage Сообщение проверки допустимости или от TagLibraryValidator или от TagExtraInfo.
VariableInfo Информация о переменных сценариев, которые создаются/изменяются тегом (во времени выполнения).
 

Пакет javax.servlet.jsp.tagext Описание

Классы и интерфейсы для определения Библиотек Тега Страниц JavaServer.

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

У пустого тега нет никакого тела. Есть два эквивалентных синтаксиса, один с отдельным запуском и конечными тэгами, и тем, где запуск и конечные тэги объединяются. Два следующих примера идентичны:

<x:foo att="myObject"></foo>
<x:foo att="myObject"/>

У непустого тега есть тег запуска, тело, и конечный тэг. Формирующий прототип пример имеет форму:

<x:foo att="myObject" >
  BODY
</x:foo/>

Страницы JavaServer (ТМ) (JSP) спецификация обеспечивают переносимый механизм для описания библиотек тега.

Библиотека тега JSP содержит

Этот API описывается в следующих разделах:

  1. Классические Обработчики Тега
  2. Обработчики тега, которые хотят получить доступ к их Контенту Тела
  3. Динамические Атрибуты
  4. Аннотируемый Пример управления Обработчиком Тега
  5. Сотрудничающие Действия
  6. Простые Обработчики Тега
  7. Фрагменты JSP
  8. Пример Простой Сценарий Обработчика Тега
  9. Разовые преобразованием Классы

1. Классические Обработчики Тега

Этот раздел представляет понятие обработчика тега и описывает классические типы обработчика тега.

JSP 2.0 представляет новый тип Обработчика Тега, названного Простым Обработчиком Тега, который описывается в более позднем разделе. Протокол для Простых обработчиков Тега является намного больше прямым.

Обработчик тега

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

Обработчик тега создается, первоначально используя нулевого конструктора параметра на его соответствующем class; метод java.beans.Beans.instantiate() не используется.

У обработчика тега есть некоторые свойства, которые представляются странице как атрибуты на действии; этими свойствами управляет контейнер JSP (через сгенерированный код). Методы метода set, используемые, чтобы установить свойства, обнаруживаются, используя JavaBeans introspector машина.

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

Экземпляр обработчика тега ответственен за обработку одного запроса за один раз. Это - responsability контейнера JSP, чтобы осуществить это.

Дополнительная информация времени преобразования, связанная с действием, указывает на имя любых переменных сценариев, которые это может представить, их типы и их контекст. В определенные моменты контейнер JSP будет автоматически синхронизироваться PageContext информация с переменными в языке сценариев, таким образом, они могут быть сделаны доступными непосредственно через элементы сценариев.

Свойства

У обработчика тега есть некоторые свойства. У всех обработчиков тега есть pageContext свойство для страницы JSP, где тег располагается, и родительское свойство для обработчика тега к самому близкому действию включения. У определенных классов обработчика тега могут быть дополнительные свойства.

Все атрибуты пользовательского действия должны быть компонентными свойствами JavaBeans, хотя некоторые свойства не могут быть представлены как атрибуты. Атрибуты, которые видимы к транслятору JSP, являются точно перечисленными в Дескрипторе Библиотеки Тега (TLD).

Все свойства экземпляра обработчика тега, представленного как атрибуты, будут инициализированы контейнером, используя соответствующие методы метода set прежде, чем экземпляр сможет использоваться, чтобы выполнить методы действия. Это - обязанность контейнера JSP вызвать соответствующие методы метода set, чтобы инициализировать эти свойства. Это - responsability пользовательского кода, быть этим scriptlets, код JavaBeans, или код в пользовательских тегах, чтобы не вызвать эти методы метода set, поскольку выполнение иначе вмешалось бы в контейнерное знание.

Методы метода set, которые должны использоваться, присваивая значение атрибуту пользовательского действия, определяются при использовании JavaBeans introspector на обработчике тега class, затем используют метод метода set, связанный со свойством, у которого есть то же самое имя как рассматриваемый атрибут. Импликация (неясный в спецификации JavaBeans) - то, что есть только один метод set на свойство.

Неуказанные атрибуты/свойства не должны быть установлены (использование метода метода set).

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

Контейнер JSP может снова использовать классические экземпляры обработчика тега для многократных возникновений соответствующего пользовательского действия в той же самой странице или в различных страницах, но только если тот же самый набор атрибутов используется для всех возникновений. Если обработчик тега используется больше чем для одного происшествия, контейнер должен сбросить все атрибуты, где значения отличаются между возникновениями пользовательского действия. Атрибуты с тем же самым значением во всех возникновениях не должны быть сброшены. Если значение атрибута устанавливается как разовое запросом значение атрибута (использующий сценарии или ЭЛЬ выражение), контейнер должен сбросить атрибут между всеми повторными использованиями экземпляра обработчика тега. Чтобы предотвратить беспорядок, обработчик тега с пустым телом не должен снова использовать предыдущий обработчик тега с непустым телом.

Пользовательский код может получить доступ к информации о свойстве и доступу и изменить внутреннее состояние обработчика тега, запускающееся с первого метода действия (doStartTag) вплоть до последнего метода действия (doEndTag или doFinally для реализации обработчиков тега TryCatchFinally).

Обработчик тега как Контейнерный управляемый объект

Так как обработчик тега является контейнерным управляемым объектом, контейнер должен поддержать свои ссылки; определенно, пользовательский код не должен сохранить ссылки на обработчик тега кроме между запуском первого метода действия (doStartTag) и концом последнего метода действия (doEndTag () или doFinally () для тех тегов та реализация TryCatchFinally).

Ограничения на ссылки, чтобы тегировать объекты-обработчики и на изменение свойств атрибута дают контейнерную существенную свободу JSP в эффективно управляющих объектах-обработчиках тега, чтобы достигнуть различных целей. Например, контейнер может, реализовывая различные стратегии объединения в пул минимизировать стоимость создания, или может поднять установку свойств, чтобы уменьшить стоимость, когда обработчик тега в другом итеративном теге.

Преобразования

Обработчик тега реализует действие; контейнер JSP должен следовать за преобразованиями типов, описанными в Разделе 2.13.2, присваивая значения атрибутам действия.

Пустые и Непустые Действия

У пустого действия нет никакого тела; это может использовать один из двух синтаксисов: любой <foo/> или <foo> </foo>. Так как у пустых действий нет никакого тела, методы, связанные с манипулированием телом, не вызываются. Есть механизм в Дескрипторе Библиотеки Тега, чтобы указать, что тег может только использоваться, чтобы записать пустые действия; когда использующийся, непустые действия, используя тот тег произведут ошибку преобразования.

У непустого действия есть тело.

Интерфейс Тега

Обработчик Тега, который не хочет обрабатывать его тело, может реализовать только интерфейс Тега. Обработчик тега, возможно, не хочет обрабатывать свое тело, потому что это - пустой тег или потому что через тело нужно только "пройти".

Интерфейс Тега включает методы, чтобы обеспечить контекстную информацию страницы для экземпляра Обработчика Тега, методы, чтобы обработать жизненный цикл обработчиков тега, и два основных метода для того, чтобы выполнить действия на теге: doStartTag() и doEndTag(). Метод doStartTag() вызывается, встречаясь с тегом запуска, и его возвращаемое значение указывает, должно ли тело (если есть кто-либо) быть пропущено, или оценено и пройтись к текущему ответному потоку. Метод doEndTag() вызывается, встречаясь с конечным тэгом; его возвращаемое значение указывает, должна ли остальная часть страницы продолжать оцениваться или нет.

Если с исключением встретятся во время оценки тела тега, то его doEndTag метод не будет оценен. См. тег TryCatchFinally для методов, которые, как гарантируют, будут оценены.

Интерфейс IterationTag

Интерфейс IterationTag используется, чтобы неоднократно переоценить тело пользовательского действия. У интерфейса есть один метод: doAfterBody() который вызывается после каждой оценки тела, чтобы определить, переоценить ли или нет.

Переоценку требуют со значением 2, который в JSP 1.1 определяется, чтобы быть BodyTag. EVAL_BODY_TAG. Та постоянная величина все еще сохраняется в JSP 1.2 (для полного назад совместимость), но, чтобы улучшить ясность, новое имя также доступно: IterationTag. EVAL_BODY_AGAIN. Чтобы прекратить выполнять итерации, возвращенное значение должно быть 0, который является Тегом. SKIP_BODY.

Интерфейс JspIdConsumer

Этот интерфейс указывает к контейнеру, что обработчик тега хочет быть предоставленным компилятор сгенерированному ID, который уникален в пределах страницы.

Базовый класс TagSupport

class TagSupport является основной class, который может использоваться, реализовывая интерфейсы Тега или IterationTag.

2. Обработчики тега, которые хотят Доступ к их Контенту Тела

Оценка тела поставляется в a BodyContent объект. Это тогда делается доступным, чтобы тегировать обработчики, которые реализуют BodyTag интерфейс. BodyTagSupport class обеспечивает полезный основной class, чтобы упростить запись этих обработчиков.

Если обработчик Тега хочет иметь доступ к контенту его тела тогда, это должно реализовать BodyTag интерфейс. Этот интерфейс расширяет IterationTag, обеспечивает два дополнительных метода setBodyContent(BodyContent) и doInitBody() и отсылает к объекту типа BodyContent.

BodyContent является подклассом JspWriter у этого есть несколько дополнительных методов, чтобы преобразовать его содержание в Строку, вставить содержание в другой JspWriter, получить Читателя в его содержание, и очистить содержание. Его семантика также гарантирует, что размер буфера никогда не будет превышаться.

Реализация страницы JSP создаст BodyContent, если doStartTag () метод возвратит EVAL_BODY_BUFFERED. Этот объект передадут к doInitBody (); тогда тело тега будет оценено, и во время той оценки будет связан с BodyContent, который только передают к обработчику BodyTag. Затем doAfterBody () будет оценен. Если тот метод возвратит SKIP_BODY, то больше оценок тела не будет сделано; если метод возвратит EVAL_BODY_AGAIN, то тело будет оценено, и doAfterBody () будет вызван снова.

Контент экземпляра BodyContent остается доступным до окончания вызова его связанного doEndTag () метод.

Обычное использование BodyContent должно извлечь свое содержание в Строку и затем использовать Строку в качестве значения для некоторой работы. Другое обычное использование должно взять свое содержание и продвинуть это в Поток, который был допустим, когда с тегом запуска встретились (который доступен от объекта PageContext, который передают к обработчику в setPageContext).

3. Динамические Атрибуты

Любой обработчик тега может дополнительно расшириться DynamicAttributes интерфейс, чтобы указать, что это поддерживает динамические атрибуты. В дополнение к реализации DynamicAttributes интерфейс, обработчики тега, которые поддерживают динамические атрибуты, должен объявить, что они делают так в Дескрипторе Библиотеки Тега.

TLD - то, что в конечном счете определяет, принимает ли обработчик тега динамические атрибуты или нет. Если обработчик тега объявляет, что поддерживает динамические атрибуты в TLD, но он не реализует DynamicAttributes интерфейс, обработчик тега должен считать недопустимым контейнер.

Если элемент динамических атрибутов для вызываемого тега содержит значение "истина", следующие требования применяются:

В следующем примере примите атрибуты a, и b объявляются, используя элемент атрибута в TLD, d1 атрибутов и d2 не объявляются, и элемент динамических атрибутов устанавливается в "истину". Атрибуты устанавливаются, используя вызовы:

<jsp:root xmlns:mytag="http://www.foo.com/jsp/taglib/mytag.tld" version="2.0">
  <mytag:invokeDynamic a="1" d1="2" mytag:d2="3">
    <jsp:attribute name="b">4</jsp:attribute>
    <jsp:attribute name="d3">5</jsp:attribute>
    <jsp:attribute name="mytag:d4">6</jsp:attribute>
  </mytag:invokeDynamic>
</jsp:root>

4. Аннотируемый Пример управления Обработчиком Тега

Ниже несколько полный пример способа, которым один контейнер JSP мог хотеть делать некоторое управление обработчиком тега. Есть много других стратегий, которые могли сопровождаться с различной платой offs.

В этом примере мы предполагаем, что x:iterate является итеративным тегом, в то время как x:doit и x:foobar являются простым тегом. Мы также предположим, что x:iterate и x:foobar реализуют интерфейс TryCatchFinally, в то время как x:doit не делает.

<x:iterate src="foo">
  <x:doit att1="one" att2="<%= 1 + 1 %>" />
  <x:foobar />
  <x:doit att1="one" att2="<%= 2 + 2 %>" />
</x:iterate>
<x:doit att1="one" att2="<%= 3 + 3 %>" />

Определенный код, показанный ниже, предполагает, что есть некоторый пул обработчиков тега, которыми управляют (детали, не описанные, хотя управление пула более просто, когда нет никаких дополнительных атрибутов), и attemps, чтобы снова использовать обработчики тега если возможный. Код также "поднимает" установку свойств, чтобы уменьшить стоимость когда приспособлено, например, в итерации.


boolean b1, b2;
IterationTag i; // for x:iterate
Tag d; // for x:doit
Tag d; // for x:foobar

page: // label to end of page...


// initialize iteration tag
i = get tag from pool or new();

i.setPageContext(pc);
i.setParent(null);
i.setSrc("foo");

// x:iterate implements TryCatchFinally
try {
    if ((b1 = i.doStartTag()) == EVAL_BODY_INCLUDE) {

        // initialize doit tag
        // code has been moved out of the loop for show
        d = get tag from pool or new();

        d.setPageContext(pc);
        d.setParent(i);
        d.setAtt1("one");

    loop:
        while (1) do {
            // I'm ignoring newlines...

            // two invocations, fused together

            // first invocation of x:doit
            d.setAtt2(1+1);
            if ((b2 = d.doStartTag()) == EVAL_BODY_INCLUDE) {
                // nothing
            } else if (b2 != SKIP_BODY) {
                // Q? protocol error ...
            }
            if ((b2 = d.doEndTag()) == SKIP_PAGE) {
                break page;  // be done with it.
            } else if (b2 != EVAL_PAGE) {
                // Q? protocol error
            }

            // x:foobar invocation
            f = get tag from pool or new();
            f.setPageContext(pc);
            f.setParent(i);

            // x:foobar implements TryCatchFinally
            try {
        
                if ((b2 = f.doStartTag()) == EVAL_BODY_INCLUDE) {
                    // nothing
                } else if (b2 != SKIP_BODY) {
                    // Q? protocol error
                }
                if ((b2 = f.doEndTag()) == SKIP_PAGE) {
                    break page;  // be done with it.
                } else if (b2 != EVAL_PAGE) {
                    // Q? protocol error
                }
            } catch (Throwable t) {
                f.doCatch(t); // caught, may been rethrown!
            } finally {
                f.doFinally();
            }

            // put f back to pool
        
            // second invocation of x:doit
            d.setAtt2(2+2);
            if ((b2 = d.doStartTag()) == EVAL_BODY_INCLUDE) {
                // nothing
            } else if (b2 != SKIP_BODY) {
                // Q? protocol error
            }
            if ((b2 = d.doEndTag()) == SKIP_PAGE) {
                break page;  // be done with it.
            } else if (b2 != EVAL_PAGE) {
                // Q? protocol error
            }

            if ((b2 = i.doAfterBody()) == EVAL_BODY_AGAIN) {
                break loop;
            } else if (b2 != SKIP_BODY) {
                // Q? protocol error
            }
        // loop
        }

    } else if (b1 != SKIP_BODY) {
        // Q? protocol error
    }

    // tail end of the IteratorTag ...

    if ((b1 = i.doEndTag()) == SKIP_PAGE) {
        break page;   // be done with it.
    } else if (b1 != EVAL_PAGE) {
        // Q? protocol error
    }
    
    // third invocation
    // this tag handler could be reused from the previous ones.
    d = get tag from pool or new();

    d.setPageContext(pc);
    d.setParent(null);
    d.setAtt1("one");
    d.setAtt2(3+3);

    if ((b1 = d.doStartTag()) == EVAL_BODY_INCLUDE) {
        // nothing
    } else if (b1 != SKIP_BODY) {
        // Q? protocol error
    }
    if ((b1 = d.doEndTag()) == SKIP_PAGE) {
        break page;  // be done with it.
    } else if (b1 != EVAL_PAGE) {
        // Q? protocol error
    }

} catch (Throwable t) {
    i.doCatch(t); // caught, may been rethrown!
} finally {
    i.doFinally();
}

5. Сотрудничающие Действия

Действия могут сотрудничать с другими действиями и со сценариями кода многими способами.

PageContext

Часто два действия в странице JSP будут хотеть сотрудничать, возможно одним действием, создающим некоторый серверный объект что потребности, которые будут получены доступ другим. Один механизм для того, чтобы сделать это, давая объект имя в пределах страницы JSP; первое действие создаст объект и свяжет имя к этому, в то время как второе действие будет использовать имя, чтобы получить объект.

Например, в следующем сегменте JSP foo действие могло бы создать серверный объект и дать ему имя "myObject". Затем bar действие могло бы получить доступ к тому серверному объекту и предпринять некоторые меры.

<x:foo id="myObject" />
<x:bar ref="myObjet" />

В реализации JSP отображающемся "имени"-> значение сохраняется неявным объектом pageContext. Этот объект раздается через экземпляры обработчика Тега, таким образом, он может использоваться, чтобы передать информацию: все это необходимо, должно знать имя, под которым информация хранится в pageContext.

Стек этапа выполнения

Альтернатива явной передаче информации через именованный объект является неявной координацией, основанной на синтаксическом определении контекста.

Например, в следующем сегменте JSP foo действие могло бы создать серверный объект; позже вложенный bar действие могло бы получить доступ к тому серверному объекту. Объект не называют в пределах pageContext: это находится потому что определенное foo элемент является самым близким экземпляром включения известного типа элемента.

<foo>
   <bar/>
</foo>

Эта функциональность поддерживается через TagSupport.findAncestorWithClass(Tag, Class), который использует ссылку, чтобы породить тег, сохраненный каждым экземпляром Тега, который эффективно обеспечивает стек выполнения времени выполнения.

6. Простые Обработчики Тега

Этот раздел представляет API, чтобы реализовать Простые Обработчики Тега. Простые Обработчики Тега представляют намного более простой протокол вызова, чем делают Классические Обработчики Тега.

Дескриптор Библиотеки Тега отображает объявления библиотеки тега на их физические базовые реализации. Простой Обработчик Тега представляется в Java class, который реализует SimpleTag интерфейс.

В отличие от классических обработчиков тега, SimpleTag интерфейс не расширяет Тег. Вместо поддержки doStartTag() и doEndTag(), SimpleTag интерфейс обеспечивает простое doTag() метод, однажды который вызывают и только однажды для любого данного вызова тега. Вся логика тега, итерация, оценки тела, и т.д. должна быть выполнена в этом единственном методе. Таким образом у простых обработчиков тега есть эквивалентное питание BodyTag, но с намного более простым жизненным циклом и интерфейсом.

Поддерживать контент тела, setJspBody() метод обеспечивается. Контейнер вызывает setJspBody() метод с a JspFragment объект, инкапсулирующий тело тега. Реализация обработчика тега может вызвать invoke() на том фрагменте, чтобы оценить тело. SimpleTagSupport удобство class обеспечивает getJspBody() и другие полезные методы, чтобы сделать это еще легче.

Жизненный цикл Простых Обработчиков Тега

Этот раздел описывает жизненный цикл простых обработчиков тега от создания до вызова. Для всей семантики, оставленной неуказанный этим разделом, значением по умолчанию семантики к тому из классического обработчика тега.

Когда простой обработчик тега вызывается, следующие шаги происходят (чтобы):

  1. Простые обработчики тега создаются, первоначально используя нулевого конструктора параметра на соответствующей реализации class. В отличие от классических обработчиков тега, этот экземпляр никогда не должен объединяться в пул контейнером. Новый экземпляр должен быть создан для каждого вызова тега.
  2. setJspContext() и setParent() методы вызываются на обработчик тега. setParent() метод нельзя вызвать, если значение, передаваемое в, null. В случае файлов тега, a JspContext обертка создается так, чтобы у файла тега, могло казаться, был свой собственный контекст страницы. Вызов getJspContext() должен возвратить обернутый JspContext.
  3. Атрибуты, определенные как атрибуты элемента XML (если кто-либо), оцениваются затем в порядке, в котором они объявляются согласно следующим правилам (называемые "оценкой атрибута элемента XML" ниже). Соответствующий бобовый метод set свойства вызывается для каждого. Если никакой метод set не определяется для указанного атрибута, но тег принимает динамические атрибуты, setDynamicAttribute() метод вызывается как метод set.
  4. Значение для каждого <jsp:attribute> элемента оценивается, и соответствующие бобовые методы метода set свойства вызываются для каждого в порядке, в котором они появляются в теле тега. Если никакой метод set не определяется для указанного атрибута, но тег принимает динамические атрибуты, setDynamicAttribute() метод вызывается как метод set.
  5. Значение для тела тега определяется, и если тело существует setJspBody() метод вызывают на обработчике тега.
  6. doTag() метод вызывается.
  7. Реализация doTag() выполняет его функцию, потенциально вызывая другие обработчики тега (если обработчик тега реализуется как файл тега), и фрагменты вызова.
  8. doTag() возвраты метода, и экземпляр обработчика тега отбрасываются. Если SkipPageException бросается, остальная часть страницы не оценивается, и запрос завершается. Если этот запрос был передан или включен от другой страницы (или Сервлет), только текущие остановки оценки страницы.
  9. Для каждой переменной сценариев тега, объявленной с контекстами AT_BEGIN или AT_END, соответствующие переменные сценариев и определяющие контекст атрибуты объявляются, как с классическими обработчиками тега.

7. Фрагменты JSP

Фрагменты JSP представляются в Java экземпляром javax.servlet.jsp.tagext.JspFragment abstract class. Части кода JSP преобразовываются во фрагменты JSP в контексте вызова тега. Фрагменты JSP создаются, обеспечивая тело <jsp:attribute> стандартного действия для атрибута, который определяется как фрагмент или типа JspFragment, или обеспечивая тело вызова тега, обработанного Простым Обработчиком Тега.

Прежде, чем быть переданным к обработчику тега, JspFragment экземпляр связывается с JspContext из окружающей страницы зависящим от реализации способом. Кроме того, это связывается с родителем Tag или SimpleTag экземпляр в целях сотрудничества, так, чтобы, когда пользовательское действие вызывается изнутри фрагмента, setParent() может быть вызван с соответствующим значением. Реализация фрагмента должна сохранить эти ассоциации для продолжительности вызова тега, в котором это используется.

invoke() метод выполняет тело и направляет весь вывод к любому переданный в java.io.Writer или JspWriter возвращенный getOut() метод JspContext связанный с фрагментом.

Реализация каждого метода может дополнительно бросить a JspException, который должен быть обработан invoker. Отметьте, что разработчики библиотеки тега и авторы страницы не должны генерировать JspFragment реализации вручную.

Следующие разделы определяют создание и жизненные циклы вызова Фрагмента JSP подробно с точки зрения Контейнера JSP.

Создание Фрагмента JSP

Когда фрагмент JSP создается, следующие шаги происходят (чтобы):

  1. Экземпляр class, реализовывая JspFragment абстрактный class получается (может или быть создан или может дополнительно кэшироваться), каждый раз, когда тег вызывается. Этот экземпляр должен быть сконфигурирован, чтобы произвести содержание тела фрагмента когда вызвано. Если фрагмент определяет тело <jsp:attribute>, фрагмент должен оценить тело каждый раз, когда это вызывается. Иначе, если фрагмент определяет тело простого тега, поведение фрагмента когда вызвано изменяется в зависимости от body-content объявленный для тега:
  2. JspFragment экземпляр передают ссылка на ток JspContext. Всякий раз, когда фрагмент вызывает обработчик тега, он должен использовать это значение, вызывая setJspContext().
  3. JspFragment экземпляр связывается с экземпляром обработчика тега самого близкого вызова тега включения, или с null если нет никакого тега включения. Всякий раз, когда фрагмент вызывает обработчик тега, фрагмент должен использовать это значение, вызывая setParent().

Вызов Фрагмента JSP

После того, как фрагмент JSP создается, его передают к обработчику тега для более позднего вызова. Фрагменты JSP могут быть вызваны или программно от обработчика тега, записанного в Java, или от файла тега, используя <jsp:invoke> или <jsp:doBody> стандартное действие.

Фрагменты JSP передают, чтобы тегировать обработчики, используя бобовое свойство типа JspFragment. Эти фрагменты могут быть вызваны, вызывая invoke() метод в JspFragment абстрактный class. Отметьте, что это является законным (и возможным) для фрагмента, чтобы рекурсивно вызвать себя, косвенно.

Следующие шаги сопровождаются, вызывая фрагмент JSP:

  1. Обработчик тега, вызывающий фрагмент, ответственен за установку значений всех объявленных AT_BEGIN и NESTED переменные в JspContext из страницы/тега вызова, прежде, чем вызвать фрагмент. Отметьте, что это - не всегда то же самое как JspContext из вызываемого фрагмента, поскольку фрагменты можно передать от одного тега до другого. В случае файлов тега, для каждой переменной объявляется в контексте AT_BEGIN или NESTED, если страница, определяющий контекст атрибут существует с обеспеченным именем в файле тега, контейнер JSP, должна генерировать код, чтобы создать/обновить страницу определяющий контекст атрибут обеспеченного имени в странице/теге вызова. Если страница, определяющий контекст атрибут с обеспеченным именем не существует в файле тега, и странице определяющий контекст атрибут обеспеченного имени, присутствует в странице вызова, определяющий контекст атрибут удаляется из контекста страницы страницы вызова. См. главу по Файлам Тега для деталей.
  2. Если <jsp:invoke> или <jsp:doBody> используются, чтобы вызвать фрагмент, если var атрибут определяется, пользовательское java.io.Writer создается, который может представить результат вызова как a java.lang.String объект. Если varReader атрибут определяется, пользовательское java.io.Writer объект создается, который может представить получающийся вызов как a java.io.Reader объект.
  3. invoke() метод фрагмента вызывается, передавая в дополнительном Writer.
  4. Прежде, чем выполнить тело фрагмента, если ненулевое значение обеспечивается для параметра писателя, то значение JspContext.getOut() и неявные возражают, должен быть обновлен, чтобы отправить вывод тому писателю. Чтобы выполнить это, контейнер должен вызвать pushBody( writer ) на токе JspContext, где writer экземпляр java.io.Writer переданный к фрагменту вызову.
  5. Тело фрагмента тогда оценивается, выполняя сгенерированный код. Тело фрагмента может выполнить другие стандартные или пользовательские действия. Если классический Пользовательский Обработчик Тега вызывается и возвращается SKIP_PAGE, или если Простой Обработчик Тега вызывается и бросает SkipPageException, JspFragment должен бросить SkipPageException сигнализировать, что страница вызова должна быть пропущена.
  6. Как только фрагмент завершил свою оценку, даже если исключение выдается, значение JspContext.getOut() должен быть восстановлен через звонок popBody() на токе JspContext.
  7. Возвраты фрагмента из вызывают ()
  8. Если <jsp:invoke> или <jsp:doBody> используются, чтобы вызвать фрагмент, если var или varReader атрибут определяется, определяющая контекст переменная с именем, равным значению var или varReader атрибут создается (или изменяется) в контексте страницы, и значение устанавливается в a java.lang.String или java.io.Reader соответственно это может привести к результатам вызова фрагмента.
  9. invoke() метод можно вызвать снова, нуль или больше раз. Когда вызов тега, определяющий фрагмент, полон, тег должен отбросить экземпляр фрагмента, так как это могло бы быть снова использовано контейнером.

8. Пример Простой Сценарий Обработчика Тега

Следующий ненормативный пример предназначается, чтобы помочь укрепить некоторые из понятий, имеющих отношение к Файлам Тега, Фрагментам JSP и Простым Обработчикам Тега. В первом разделе два демонстрационных входных файла представляются, JSP (my.jsp), и простой обработчик тега реализовывал использование файла тега (simpletag.tag). Один возможный вывод процесса перевода представляется во втором разделе.

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

Сгенерированный код выборки аннотируется комментариями, которые указывают на шаги жизненного цикла, представленные в различных разделах. Нотация следующие:

Демонстрационные Исходные файлы

Этот раздел представляет демонстрационные исходные файлы в этом сценарии, из которого сгенерированы выходные файлы.

Исходный JSP (my.jsp)

<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>

<my:simpleTag x="10">
    <jsp:attribute name="y">20</jsp:attribute>
    <jsp:attribute name="nonfragment">
        Nonfragment Template Text
    </jsp:attribute>
    <jsp:attribute name="frag">
        Fragment Template Text ${var1}
    </jsp:attribute>
    <jsp:body>
        Body of tag that defines an AT_BEGIN
        scripting variable ${var1}.
    </jsp:body>
</my:simpleTag>

Исходный Файл Тега (/WEB-INF/tags/simpletag.tag)

<%-- /WEB-INF/tags/simpletag.tag --%>
<%@ attribute name="x" %>
<%@ attribute name="y" %>
<%@ attribute name="nonfragment" %>
<%@ attribute name="frag" fragment="true" %>
<%@ variable name-given="var1" scope="AT_BEGIN" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

Some template text.
<c:set var="var1" value="${x+y}"/>
<jsp:invoke fragment="frag" varReader="var1"/>

Invoke the body:
<jsp:doBody/>

Демонстрационные Сгенерированные Файлы

Этот раздел представляет демонстрационные выходные файлы, которые могли бы быть сгенерированы компилятором JSP от исходных файлов, представленных в предыдущем разделе.

Помощник class для JspFragment (JspFragmentBase.java)

public abstract class JspFragmentBase
    implements javax.servlet.jsp.tagext.JspFragment
{
    protected javax.servlet.jsp.JspContext jspContext;
    protected javax.servlet.jsp.tagext.JspTag parentTag;
    public void JspFragmentBase(
        javax.servlet.jsp.JspContext jspContext,
        javax.servlet.jsp.tagext.JspTag parentTag )
    {
        this.jspContext = jspContext;
        this.parentTag = parentTag;
    }
}

Соответствующая Часть Метода Службы JSP

// Step T.1 - Initial creation
MySimpleTag _jsp_mySimpleTag = new MySimpleTag();
// Step T.2 - Set page context and parent (since parent is null,
// no need to call setParent() in this case)
_jsp_mySimpleTag.setJspContext( jspContext );
// Step T.3 - XML element attributes evaluated and set
_jsp.mySimpleTag.setX( "10" );
// Step T.4 - <jsp:attribute> elements evaluated and set
//   - parameter y
// (using PageContext.pushBody() is one possible implementation - 
// one limitation is that this code will only work for Servlet-based code).
out = ((PageContext)jspContext).pushBody();
out.write( "20" );
_jsp_mySimpleTag.setY( 
    ((javax.servlet.jsp.tagext.BodyContent)out).getString() );
out = jspContext.popBody();
//   - parameter nonfragment
// (using PageContext.pushBody() is one possible implementation - 
// one limitation is that this code will only work for Servlet-based code).
// Note that trim is enabled by default, else we would have "\n    Non..."
out = ((PageContext)jspContext).pushBody();
out.write( "Nonfragment Template Text" );
_jsp_mySimpleTag.setNonfragment( 
    ((javax.servlet.jsp.tagext.BodyContent)out).getString() );
out = jspContext.popBody();
//   - parameter frag
_jsp_mySimpleTag.setFrag(
    // Step C.1 - New instance of fragment created
    // Step C.2 - Store jspContext
    // Step C.3 - Association with nearest enclosing Tag instance
    new JspFragmentBase( jspContext, _jsp_mySimpleTag ) {
        public void invoke( java.io.Writer writer ) {
            javax.servlet.jsp.JspWriter out;
            // Step F.1-F.3 done in tag file (see following example)
            // Step F.4 - If writer provided, push body:
            if( out == null ) {
                out = this.jspContext.getOut();
            }
            else {
                out = this.jspContext.pushBody( writer );
            }
            // Step F.5 - Evaluate body of fragment:
            try {
                out.write( "Fragment Template Text " );
                out.write( jspContext.getExpressionEvaluator().evaluate(
                    "${var1}",
                    java.lang.String.class,
                    vResolver, fMapper, "my" ) );
            }
            finally {
                // Step F.6 - Restore value of JspContext.getOut()
                if( writer != null ) {
                    this.jspContext.popBody();
                }
            }

            // Step F.7-F.9 done in tag file (see following example)
        }
    } );
// Step T.5 - Determine and set body of the tag
// - body of tag
_jsp_mySimpleTag.setJspBody(
    // Step C.1 - New instance of fragment created
    // Step C.2 - Store jspContext
    // Step C.3 - Association with nearest enclosing Tag instance
    new JspFragmentBase( jspContext, _jsp_mySimpleTag ) {
        public void invoke( java.io.Writer writer ) {
            javax.servlet.jsp.JspWriter out;
            // Step F.1-F.3 done in tag file (see following example)
            // Step F.4 - If writer provided, push body:
            if( writer == null ) {
                out = this.jspContext.getOut();
            }
            else {
                out = this.jspContext.pushBody( writer );
            }
            // Step F.5 - Evaluate body of fragment:
            try {
                out.write(
                    "Body of tag that defines an AT_BEGIN\n" +
                    " scripting variable " );
                out.write( jspContext.getExpressionEvaluator().evaluate(
                    "${var1}",
                    java.lang.String.class,
                    vResolver, fMapper, "my" ) );
                out.write( ".\n" );
            }
            finally {
                // Step F.6 - Restore value of JspContext.getOut()
                if( writer != null ) {
                    this.jspContext.popBody();
                }
            }

            // Step F.7-F.9 done in tag file (see following example)
        }
    } );
// Step T.6 - Inovke doTag
// Step T.7 occurs in the tag file (see following example)
// Step T.8 - doTag returns - page will catch SkipPageException.
_jsp_mySimpleTag.doTag();
// Step T.9 - Declare AT_BEGIN and AT_END scripting variables
String var1 = (String)jspContext.findAttribute( "var1" );

Сгенерированный Простой Обработчик Тега (MySimpleTag.java)

public class MySimpleTag
    extends javax.servlet.jsp.tagext.SimpleTagSupport
{
    // Attributes:
    private String x;
    private String y;
    private String nonfragment;
    private javax.servlet.jsp.tagext.JspFragment frag;
    // Setters and getters for attributes:
    public void setX( Stirng x ) {
        this.x = x; 
    }
    public String getX() {
        return this.x; 
    }
    public void setY( String y ) { 
        this.y = y; 
    }
    public String getY() { 
        return this.y; 
    }
    public void setNonfragment( String nonfragment ) {
        this.nonfragment = nonfragment; 
    }
    public String getNonfragment() {
        return this.nonfragment;
    }
    public void setFrag( javax.servlet.jsp.tagext.JspFragment frag ) {
        this.frag = frag;
    }
    public javax.servlet.jsp.tagext.JspFragment getFrag() {
        return this.frag;
    }

    protected JspContext jspContext;
    public void setJspContext( JspContext ctx ) {
        super.setJspContext( ctx );
        // Step T.2 - A JspContext wrapper is created.
        // (Implementation of wrapper not shown).
        this.jspContext = new utils.JspContextWrapper( ctx );
    }
    public JspContext getJspContext() {
        // Step T.2 - Calling getJspContext() must return the 
        // wrapped JspContext.
        return this.jspContext;
    }

    public void doTag() throws JspException {
        java.lang.Object jspValue;
        JspContext jspContext = getJspContext();
        JspContext _jsp_parentContext = 
            SimpleTagSupport.this.getJspContext();
        try {
            javax.servlet.jsp.JspWriter out = jspContext.getOut();

            // Create page-scope attributes for each tag attribute:
            this.jspContext.setAttribute( "x", getX() );
            this.jspContext.setAttribute( "y", getY() );
            this.jspContext.setAttribute( "nonfragment", getNonfragment() );
            this.jspContext.setAttribute( "frag", getFrag() );

            // Synchronize AT_BEGIN variables from calling page
            if( (jspValue = _jsp_parentContext.getAttribute( 
                    "var1" )) != null ) 
            {
                jspContext.setAttribute( "var1", value );
            }
            else {
                jspContext.removeAttribute( "var1", 
                    JspContext.PAGE_SCOPE );
            }

            // Tag template text:
            out.write( "\n\n\n\n\n\n\n\nSome template text.\n" );

            // Invoke c:set - recognized tag handler from JSTL:
            jspContext.setAttribute( "var1", 
                jspContext.getExpressionEvaluator().evaluate(
                    "${x+y}",
                    java.lang.String.class,
                    jspContext,
                    prefixMap, functionMap, "my" ) );

            // Invoke the "frag" fragment:
            // Step F.1 - Set values of AT_BEGIN and NESTED variables
            //     in calling page context.
            if( (jspValue = jspContext.getAttribute( "var1" )) != null ) {
                _jsp_parentContext.setAttribute( "var1", value );
            }
            else {
                _jsp_parentContext.removeAttribute( "var1", 
                    JspContext.PAGE_SCOPE );
            }

            // Step F.2 - varReader is specified, generate a writer.
            java.io.Writer _jsp_sout = new java.io.StringWriter();

            // Step F.3 - Invoke fragment with writer
            getFrag().invoke( _jsp_sout );

            // Step F.4 - F.6 occur in the fragment (see above)
            // Step F.7 - fragment returns

            // Step F.8 - varReader specified, so save to var
            jspContext.setAttribute(
                "var1", new StringReader( _jsp_sout.toString() ) );

            // Step F.9 - Done!


            out.write( "\n\nInvoke the body:\n" );

            // Invoke the body of the tag:
            // Step F.1 - Set values of AT_BEGIN and NESTED variables
            //     in calling page context.
            if( (jspValue = jspContext.getAttribute( "var1" )) != null ) {
                _jsp_parentContext.setAttribute( "var1", value );
            }
            else {
                _jsp_parentContext.removeAttribute( "var1", 
                    JspContext.PAGE_SCOPE);
            }

            // Step F.2 - varReader is not specified - does not apply.

            try {
                // Step F.3 - Invoke body, passing optional writer
                getJspBody().invoke( null );
            }
            finally {
                // Steps F.4 - F.6 occur in the fragment (see above)
                // Step F.7 - fragment returns
            }

            // Step F.8 does not apply.
            // Step F.9 - Done!
        }
        finally {
            // Tag handlers generate code to synchronize AT_BEGIN with
            // calling page, regardless of whether an error occurs.
            if( (jspValue = jspContext.getAttribute( "var1" )) != null ) {
                _jsp_parentContext.setAttribute( "var1", value );
            }
            else {
                _jsp_parentContext.removeAttribute( "var1", 
                    JspContext.PAGE_SCOPE );
            }
        }
    }
}

9. Разовые преобразованием Классы

Во время преобразования используются следующие классы.

Отображение тега, Имя тега

taglib направляющее представляет библиотеку тега и связывает префикс к этому. TLD, связанный с библиотекой, связывает классы обработчика Тега (плюс другая информация) с именами тега. Эта информация используется, чтобы связать Тег class, префикс, и имя с каждым элементом пользовательского действия, появляющимся в странице JSP.

Во время выполнения реализация страницы JSP будет использовать доступный экземпляр Тега с соответствующими настройками свойства и затем следовать за протоколом, описанным Тегом интерфейсов, IterationTag, BodyTag, SimpleTag, и TryCatchFinally. Реализация гарантирует, что все экземпляры обработчика тега инициализируются, и все выпускаются, но реализация может предположить, что предыдущие настройки сохраняются обработчиком тега, чтобы уменьшить затраты времени выполнения.

Сценарии Переменных

JSP поддерживает переменные сценариев, которые могут быть объявлены в пределах scriptlet и могут использоваться в другом. Действия JSP также могут использоваться, чтобы определить переменные сценариев, таким образом, они могут используемый в сценариях элементов, или в других действиях. Это очень полезно в некоторых случаях; например, jsp:useBean стандартное действие может определить объект, который может позже использоваться через переменную сценариев.

В некоторых случаях информация о сценариях переменных может быть описана непосредственно в TLD использование элементов. Особый случай является типичной интерпретацией атрибута "идентификатора". В других случаях логика, которая решает, определит ли экземпляр действия переменную сценариев, может быть довольно сложной и имя a TagExtraInfo class вместо этого дается в TLD. getVariableInfo метод этого class используется во время преобразования, чтобы получить информацию о каждой переменной, которая будет создаваться во время запроса, когда это действие будет выполнено. Метод передают a TagData экземпляр, который содержит разовые преобразованием значения атрибута.

Проверка допустимости

Файл TLD содержит несколько сведений, который используется, чтобы сделать синтаксическую проверку допустимости в разовом преобразованием. Это также содержит два расширяемых механизма проверки допустимости: a TagLibraryValidator class может использоваться, чтобы проверить полной страницы JSP, и a TagExtraInfo class может использоваться, чтобы проверить определенного действия. В некоторых случаях дополнительная разовая запросом проверка допустимости будет сделана динамически в пределах методов в экземпляре Тега. Если ошибка обнаруживается, экземпляр JspTagException может быть брошен. Если непойманный, этот объект вызовет errorpage механизм JSP.

TagLibraryValidator является дополнением к JSP 1.2 спецификации и очень открыт законченный, будучи строго более мощным чем механизм TagExtraInfo. Страница JSP представляется через PageData объект, который абстрагирует режим просмотра XML страницы JSP.

Экземпляр PageData будет предоставлять InputStream (только для чтения) на странице. Более поздние спецификации могут добавить другие представления на странице (ДОМ, SAX, JDOM являются всеми кандидатами), пока эти представления могут быть сгенерированы от InputStream и возможно могут кэшироваться для улучшенной производительности (вспомните, что представление страницы только только для чтения).

С JSP 2.0, контейнер JSP должен поддерживать атрибут jsp:id, чтобы обеспечить более высокие качественные ошибки проверки допустимости. Контейнер отследит страницы JSP как передано к контейнеру, и присвоит каждому элементу уникальный "идентификатор", который передают как значение атрибута jsp:id. Каждый элемент XML в режиме просмотра XML будет расширен с помощью этого атрибута. TagLibraryValidator может использовать атрибут в одном или более объектах ValidationMessage. Контейнер тогда, поочередно, может использовать эти значения, чтобы предоставить более точную информацию о расположении ошибки.

Префикс для id припишите не должен быть"jsp"но это должно отобразиться на пространство имен http://java.sun.com/JSP/Page. В случае, где пользователь пересмотрел jsp префикс, альтернативный префикс должен использоваться контейнером.

Детали проверки допустимости

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

Во-первых, страница JSP анализируется, используя информацию в TLD. На данном этапе допустимые обязательные и дополнительные атрибуты проверяются.

Во-вторых, для каждой уникальной библиотеки тега в странице как определено URI библиотеки тега, и в лексическом порядке, в котором они появляются, их связанный блок проверки допустимости class (если кто-либо) вызывается. Это включает несколько подшагов.

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

Имя class как обозначается в <блок-проверки-допустимости-class> элемент, и Карта, через которую проходят, setInitParameters () как описывается в <init-params> элементе. Все классы TagLibraryValidator, как предполагается, сохраняют свой initParameters, пока новые не устанавливаются, или пока выпуск () вызывается на них.

Второй подшаг должен выполнить фактическую проверку допустимости. Это делается, вызывая проверение () метод с префиксом, турами, и PageData, которые соответствуют taglib направляющему проверяемому экземпляру и PageData, представляющий страницу. В случае, где единственный URI отображается больше чем на один префикс, должен использоваться префикс первого URI.

Последний подшаг должен вызвать выпуск () метод на теге блока проверки допустимости, когда это больше не необходимо. Этот метод высвобождает все средства.

Наконец, после проверки всех классов блока проверки допустимости библиотеки тега, с классами TagExtraInfo для всех тегов будут консультироваться, вызывая их validate метод. Порядок вызова этого методы неопределен.



Представьте ошибку или функцию

Авторское право © 2009-2011, Oracle Corporation и/или его филиалы. Все права защищены. Использование подвергается срокам действия лицензии.

Сгенерированный на 10-February-2011 12:41

free hit counter