Ниже дан довольно полный пример того, как 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) {