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();
}