Я только что внес ошибку в свой код, потому что, похоже, неправильно понял жизненный цикл тега jsp.
Тег работал так до ошибки: я передаю тегу некоторую коллекцию в качестве атрибута, и он отображает его в виде таблицы. Коллекция была передана в JSP от контроллера.
После ошибки: я удалил атрибут, который устанавливал коллекцию. Вместо этого в теге я проверяю, является ли коллекция нулевой, а затем беру ее по имени из запроса (используя соглашение об именах).
То, чего я не ожидал: после того, как коллекция была изначально установлена в теге, она никогда не станет нулевой при последующих выполнениях! Он все еще был определен как необязательный атрибут в TLD.
Я ожидал, что тег не сохранит предыдущие значения между выполнениями.
Ответ 1 · рейтинг 12 · Olaf Kock
Вы сами ответили на вопрос - он объединен. См. руководство по тегам, чтобы узнать, что реализовать в реализациях Java вместе с страница, на которую имеется ссылка оттуда, содержащая последовательность вызова:
ATag t = new ATag();
t.setPageContext(...);
t.setParent(...);
t.setAttribute1(value1);
t.setAttribute2(value2);
t.doStartTag();
t.doEndTag();
t.release();
То есть повторно инициализируйте свой экземпляр тега в doEndTag () в соответствии с требованиями API. (изменено на момент комментария Жюльена Кронегга, спасибо)
Обратите внимание, что объединение, вероятно, зависит от контейнера, но вполне законно (и, из-за настройки API, вероятно, выполняется везде).
Ответ 2 · рейтинг 8 · user196621
Краткий ответ: вы не должны сами писать атрибутные свойства. Поступая так, вы возьмете на себя ответственность за очистку состояния.
Чтобы получить более подробный ответ, JSP 2.0 Spec предписывает следующее (стр. 2-51) :
- Установщики вызываются для всех указанных атрибутов определенного вхождения тега
- Сеттеры не вызываются для пропущенных атрибутов (оставляя значения по умолчанию нетронутыми и, в вашем случае, недопустимое значение во внутреннем состоянии)
- Обработчики тегов могут быть повторно использованы только экземплярами с тем же набором указанных атрибутов.
Эти три точки вместе гарантируют, что свойства атрибута всегда правильно инициализируются, сохраняя при этом значения по умолчанию (определенные в конструкторе или объявлении свойств). В свою очередь, он работает только в предположении, что только контейнер управляет свойствами атрибута (вызывая сеттеры).
Для полноты:
release() не следует использовать для сброса внутреннего состояния между вызовами обработчика тега. Он гарантированно вызывается только перед сборкой мусора и должен использоваться для освобождения долгосрочных ресурсов.
- Если вы хотите инициализировать переменные экземпляра в
doStartTag(), будьте осторожны, чтобы не перезаписать атрибуты, потому что в этот момент установщики уже были вызваны контейнером.
doEndTag() следует безопасно использовать для инициализации, потому что теги никогда не должны использоваться повторно в случае исключения (см. Стр. 2-54 [2])
Ответ 5 · Community
Наблюдение за Tomcat 6 предполагает, что release () вызывается только при закрытии контейнера. Члены экземпляра обработчика тега должны очищать состояние экземпляра в doEndTag (). Из документа api:
"Все состояния экземпляра, связанные с этим экземпляром, должны быть сброшены".
см. TagSupport.doEndTag ()