Спецификация Java Server Pages 1.2

       

JSP.10.3 Пример Работы с Аннотированным Обработчиком Тэга


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


Есть и другие стратегии, которым можно следовать.

В данном примере мы принимаем, что 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 %>”/>

Код, показанный ниже, принимает, что имеется обслуживаемый пул обработчиков тэгов (детали не описаны, хотя обслуживание пула проще, если нет атрибутов по выбору), и пытается использовать обработчики тэгов повторно, если это возможно. Этот код “крадёт” установки этих свойств для уменьшения затрат, где это возможно, например, при итерации.

boolean b1, b2;
IterationTag i; // для x:iterate

Tag d; // для x:doit
Tag d; // для x:foobar

page: // лэйбл для конца страницы...
// инициализируется тэг итерации
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) {

         // инициализируется тэг doit
         // код выводится из цикла для показа

         d = get tag from pool or new();

         d.setPageContext(pc);
         d.setParent(i);
         d.setAtt1(“one”);
    loop:
      while (1) do {
      // Игнорирую символы новой строки...
      // два вызова, сплавленные вместе
      // первый вызов x:doit
      d.setAtt2(1+1);
      if ((b2 = d.doStartTag()) == EVAL_BODY_INCLUDE) {
          // ничего
      } else if (b2 != SKIP_BODY) {
         // Q? ошибка протокола ...
      }
      if ((b2 = d.doEndTag()) == SKIP_PAGE) {


           break page; // выполняется им.
      } else if (b2 != EVAL_PAGE) {
           // Q? ошибка протокола
      }

// вызов x:foobar
      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) {

             // ничего
         } else if (b2 != SKIP_BODY) {
            // Q? ошибка протокола
         }
         if ((b2 = f.doEndTag()) == SKIP_PAGE) {
             break page; // выполняется им.
         } else if (b2 != EVAL_PAGE) {
            // Q? ошибка протокола
         }
} catch (Throwable t) {
         f.doCatch(t); // отловлено, может быть повторно отловлено!

} finally {
         f.doFinally();
}
// помещает f обратно в пул

// второй вызов x:doit
d.setAtt2(2+2);

if ((b2 = d.doStartTag()) == EVAL_BODY_INCLUDE) {
    // ничего
} else if (b2 != SKIP_BODY) {
   // Q? ошибка протокола
}
if ((b2 = d.doEndTag()) == SKIP_PAGE) {
    break page; // выполняется им.
} else if (b2 != EVAL_PAGE) {
   // Q? ошибка протокола
}
if ((b2 = i.doAfterBody()) == EVAL_BODY_AGAIN) {
   break loop;
} else if (b2 != SKIP_BODY) {
   // Q? ошибка протокола
}

// цикл
}

} else if (b1 != SKIP_BODY) {
// Q? ошибка протокола
}

// конец IteratorTag ...
if ((b1 = i.doEndTag()) == SKIP_PAGE) {
   break page; // выполняется им.
} else if (b1 != EVAL_PAGE) {
   // Q? ошибка протокола
}

// третий вызов
// этот обработчик тэга может быть повторно использован из предыдущего.

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) {
   // ничего
} else if (b1 != SKIP_BODY) {
   // Q? ошибка протокола
}
if ((b1 = d.doEndTag()) == SKIP_PAGE) {
   break page; // выполняется им.
} else if (b1 != EVAL_PAGE) {
   // Q? ошибка протокола
}
}catch (Throwable t){
i.doCatch(t); // отловлено, может быть повторно отловлено!

} finally {
i.doFinally();
}


Содержание раздела