Этот тест был вызван чтением вопроса на форумах Sun java и я решил попробовать его.
Раздел спецификации JSP2.0 JSP.13.8 содержит «Пример сценария простого обработчика тегов». Я скопировал и вставил фрагменты кода и попытался запустить его.
Окружающая среда:
Apache Tomcat версии 5.5.26 и 6.0.14 (протестировано на обоих)
Java: 1,5
Код, с которым я тестирую:
JSP страница:
<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
<my:simpletag x="10">
<jsp:attribute name="y">20</jsp:attribute>
<jsp:attribute name="nonfragment">
Nonfragment Template Text
</jsp:attribute>
<jsp:attribute name="frag">
Fragment Template Text ${var1}
</jsp:attribute>
<jsp:body>
Body of tag that defines an AT_BEGIN
scripting variable ${var1}.
</jsp:body>
</my:simpletag>
И файл тегов:
<%-- /WEB-INF/tags/simpleTag.tag --%>
<%@ attribute name="x" %>
<%@ attribute name="y" %>
<%@ attribute name="nonfragment" %>
<%@ attribute name="frag" fragment="true" %>
<%@ variable name-given="var1" scope="AT_BEGIN" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Some template text.
<c:set var="var1" value="${x+y}"/>
<jsp:invoke fragment="frag" varReader="var1"/>
Invoke the body:
<jsp:doBody/>
Этот код напрямую скопирован из PDF-копии спецификации JSP2.0.
Он также доступен как часть JSP-API здесь
Незначительное изменение - я изменил имя файла тега с simpletag.tag на simpleTag.tag, чтобы соответствовать его вызову в JSP.
Я также попытался скопировать из PDF спецификации (корректируя кавычки по мере необходимости) - тот же результат.
Когда я выполняю страницу, я получаю стандартную ошибку 500
Первопричина:
java.lang.ClassCastException: java.io.StringReader
org.apache.jsp.tagVariableTest_jsp._jspService (tagVariableTest_jsp.java:62)
Line62 сгенерированной JSP оказывается:
var1 = (java.lang.String) _jspx_page_context.findAttribute ("var1");
Хорошо, я могу понять ClassCastException - он думает, что var1 должен быть String, а фактический атрибут - StringReader. Но почему это StringReader? Где была создана переменная? И почему он вообще пытается выполнить это задание?
Может кто-нибудь, пожалуйста, указать мне в правильном направлении?
Что не так с кодом / настройкой?
Это известная проблема? Я погуглил, но, похоже, ничего не нашел.
Спасибо,
evnafets
Редактирование с разрешением:
ClassCastException вызывалось строкой в теге:
<jsp:invoke fragment="frag" varReader="var1"/>
Как уже упоминалось здесь атрибут varReader указывает атрибут для хранения результата оценки в виде StringReader. Исключение было вызвано сгенерированным Tomcat кодом, который пытался получить значение «var1» и привести его к строке. Поскольку String не является StringReader, он вызвал исключение в этой точке.
Я не уверен, если ошибка кодирования заключается в том, что они должны были использовать «var» вместо атрибута «varReader», или они не должны были использовать их и просто оценивали это как есть.
При удалении этого атрибута полностью распечатывается фрагмент, а затем тело как со значением «var1»:
Фрагмент шаблона текста 30.
Вызвать тело: тело тега, определяющего переменную сценария AT_BEGIN 30
Создание атрибута var = "var1" выполняет фрагмент и сохраняет результат в var1. Затем тело оценивается с помощью этого нового значения var1, что приводит к:
Вызвать тело: тело тега, определяющего переменную сценария AT_BEGIN. Текст шаблона фрагмента 30
Лично я думаю, что первый случай имеет больше смысла, но этот код представлен как пример внутренней работы, а не передовой практики.
Я все еще ожидал бы, что пример скомпилирует / запустит в любом случае. Я был довольно удивлен, когда это не так.