Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТАБЛИЦА ТЭГОВ HTML.doc
Скачиваний:
25
Добавлен:
12.05.2015
Размер:
401.41 Кб
Скачать

Тэги, которые управляют содержимым своего тела

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

Давайте взглянем на тэг, который реально интересуется содержимым своего тела.

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

Это была темная и штормовая ночь...

Это может быть выполнено в HTML достаточно примитивным образом, с помощью использования текста заголовка и таблиц, которые служат для наших целей, но прежде, чем писать таблицу каждый раз, когда вы хотите разбить символы, почему бы не создать тэг, которые делает это за вас? В идеале он должен делать что-то типа такого:

<tijtags:dropcapitaltag color = "black">

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

</tijtags:dropcapitaltag>

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

Чтобы создать этот тэг, нам необходимо выполнить следующие важные задачи:

Написать класс, который реализует интерфейс Tag.

Дать классу метод setColor( ), который позволит контейнеру устанавливать атрибут цвета.

Написать код, который читает содержимое тела и вставляет соответствующие тэги HTML, чтобы первый символ отображался, как отдельный символ.

Создать файл дескриптора библиотеки тэга для тэга.

Давайте взглянем на код этого тэга:

package cx2.tags;

import javax.servlet.jsp.tagext.BodyTagSupport;

import javax.servlet.jsp.tagext.TryCatchFinally;

import javax.servlet.jsp.JspException;   

import java.util.StringTokenizer;

public class DropCapitalTag extends BodyTagSupport implements TryCatchFinally {

   String color = "black";

 

   public void setColor(String color) {

      this.color = color;

   }

  

   public int doAfterBody() throws JspException {

      int period;

      StringBuffer result = new StringBuffer();

      String body = bodyContent.getString().trim();

      result.append("<table><tr><td><h1><font color=\""+color+"\">");

     result.append(Character.toUpperCase(body.charAt(0)));

      result.append("</font></h1></td><td>");

      period = body.indexOf('.');

      result.append (body.substring(1, period+1));

      result.append ("</td></tr></table>");

      result.append (body.substring(period +1, body.length()));

      try {

         if (result.length() > 0) {

            bodyContent.clearBody();

            bodyContent.println(result.toString());

         }

         bodyContent.writeOut(bodyContent.getEnclosingWriter());

      } catch(Exception e) {

         e.printStackTrace();

      }

      return SKIP_BODY;

   }

   public void doCatch(Throwable t) {

      System.out.println(

        "An error occurred with the message" +

        t.getMessage());

   }

   public void doFinally() {}

   public void release() {

      color = "black";

   }

}

Первое, что вы заметите, это то, что в отличие от предыдущего тэга, этот тэг не реализует интерфейс Tag. Это происходит потому, что когда вам необходимо управлять содержимым тела, более полезно расширять класс BodyTagSupport, который берет на себя заботу о сохранении объекта pageContext и предоставлении реализации по умолчанию для методов doStartTag( ) и doEndTag( ). Этот класс реализует интерфейс Tag, так что вам не нужно делать это.

Метод doAfterBody( ) этого тэга является тем методом, где все происходит. Вы увидите, что этот класс ссылается на обработчик, называемый bodyContent. Это ссылка на объект BodyContent, который находится в пакете javax.servlet.jsp.tagext. Он предоставляется контейнером через метод setBodyContent( ) и является ничем иным, что мы свободно получаем во время наследования класса BodyTagSupport. Этот контейнер будет всегда предоставлять этот объект до того, как он вызовет метод doInitBody( ), так что вы всегда гарантированы в том, что у вас есть действительный объект BodyContent в ваших методах doInitBody(), doAfterBody(), doStartTag и doEndTag().

Объект BodyContent является инкапсуляцией содержимого тела этого конкретного тэга, он содержит весь текст из JSP страницы, который находится между начальным и конечным тэгом. Это очень сильно похоже на выходной поток, но с некоторой дополнительной функциональностью. Этот объект дает вам доступ к JSP тексту. Вот что делает тэг отделения заглавной буквы и вот что вам необходимо сделать, если вы хотите манипулировать содержимым тела. Вы можете получить тело целиком в виде строки, посредством вызова getString( ), или в виде потока, используя метод getReader( ), если это более подходит вашим нуждам.

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

После того, как были добавлены HTML тэги (с помощью объекта StringBuffer для добавления строк), появляется длинная строка, которой необходимо заменить старый текст. Чтобы сделать это, сначала вызывается метод clearBody( ) из BodyContent. Если вы не сделаете этого, содержимое тела появится в браузере дважды. Далее, мы используем метод println( ), чтобы добавить новую строку в BodyContent, и, наконец, вызывается метод writeOut( ). Этот метод сообщает объекту BodyContent о перенаправлении его вывода в браузер, но вы заметите, что этот метод принимает JspWriter в качестве параметра, а в этом случае writer получается из вызова getEnclosingWriter( ). Вам нужно сделать это, поскольку объект содержимого тела включает только тело вашего определенного тэга и вам необходимо получить доступ к выходному потоку, который направляет вывод клиентскому браузеру.

Если вы рассмотрите более подробно, вы увидите, что метод release( ) не делает ничего. Этот метод будет вызван контейнером для высвобождения своего состояния, так что его лучше использовать для высвобождения ресурсов, которые вы можете использовать в тэге. Имейте в виду, что может быть несколько вызовов doStartTag( ) и doEndTag( ) и между каждым из них вызывается release, так что это не тот метод, который нужно использовать для выполнения операций, выполняющихся каждый раз, при завершении обработки тэга. Если вы хотите сделать это, вам лучше всего использовать doFinally( ), описанный в следующем параграфе.

Вы можете заметить, что этот класс реализует интерфейс TryCatchFinally, находящийся в пакете javax.servlet.jsp.tagext. Когда контейнер видит, что ваш тэг реализует этот интерфейс, он знает, что нужно поместить блок try/catch вокруг обработчика тэга и, в случае возникновения исключения, передать обработку вам. Это значит, что вы получаете максимальный контроль над кодом обработки исключений и, если захотите, вы можете предотвратить отображение текста возникшего исключения в окне браузера.

Методы интерфейса TryCatchFinally - это doCatch( ) и doFinally( ) и они соответствуют ключевым словам catch и finally в Java. Метод doCatch( ) вызывается, если возникает исключение, исключение передается в него в качестве параметра, а doFinally( ) вызывается всегда, независимо от того, что случилось в других методах обработчика тэга. В этом примере, если возникнет исключение, на консоли сервера, а не в клиентском браузере, просто возникнет сообщение. Это немного ленивый подход к дизайну, использующийся для демонстрации интерфейса. Алгоритм, использованный здесь, не очень устойчивый, так что легко может возникнуть исключение. В приведенном выше методе doFinally( ) устанавливается черный цвет, так как это всегда значение по умолчанию.

Используйтесь этот интерфейс с осторожностью. Его основное назначение состоит в том, чтобы дать вам больший контроль, когда обрабатываете ресурсы такие, как потоки и т.п. Помните, что исключения относятся к восстановлению и может быть более подходящим обработать исключения в ваших методах doAfterBody( ) или doInitBody( ) и произвести некоторый имеющий смысл вывод для отображения в клиентском браузере, например страницы с ошибкой, которая попросит пользователя ввести повторно некоторые детали. Вы можете захотет просто перенаправить браузеру общую страницу сообщения об ошибке, если это больше подходит.

Теперь, когда вы уже увидели, как реализован класс, давайте взглянем на запись о тэге в файле дескриптора библиотеки тэга. Она выглядит так:

.. 

<tag>

   <name>dropcapitaltag</name>

   <tagclass>cx2.tags.DropCapitalTag</tagclass>

   <bodycontent>JSP</bodycontent>

    <info> Transforms text to have a drop capital.

    </info>

    <attribute>

       <name>color</name>

      <required>false</required>

    </attribute>

  </tag>

..

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

Вот и все, что вам нужно сделать для манипуляции телом тэга!

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]