这个测试是通过阅读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/>
此代码直接从 JSP2.0 规范的 PDF 副本中复制而来。
它也可以作为 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)
生成的 JSP 的第 62 行原来是: var1 = (java.lang.String) _jspx_page_context.findAttribute("var1");
好的,我可以理解 ClassCastException - 它认为 var1 应该是一个字符串,而实际的属性是一个 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
我个人认为第一种情况更有意义,但此代码是作为内部工作的示例,而不是最佳实践。
在任何情况下,我仍然希望该示例能够编译/运行。当它没有时,我相当惊讶。