JSP.13.8 示例简单标记处理程序场景不起作用?

发布于 2024-07-14 12:45:39 字数 2969 浏览 6 评论 0原文

此测试是通过阅读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 应该是一个 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 脚本变量 Fragment Template Text 30 的标记正文

个人认为第一种情况更有意义,但此代码是作为内部工作的示例提供的,而不是最佳实践。
我仍然希望该示例在任何情况下都能编译/运行。 当它没有出现时,我感到相当惊讶。

This test was prompted by reading a question on the Sun java forums and thought I would try it out.
The JSP2.0 specification section JSP.13.8 contains an "Example Simple Tag Handler Scenario". I copy and pasted the code fragments and attempted to run it.

Environment:
Apache Tomcat version 5.5.26 and 6.0.14 (tested on both)
Java: 1.5

Code I am testing with:
Jsp page:

<%@ 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>

And the tag file:

<%-- /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/>

This code is directly copied from the PDF copy of the JSP2.0 specification.
It is also available as part of the JSP-API here
Minor change made - I changed the name of the tagfile from simpletag.tag to simpleTag.tag to match the invocation of it in the JSP.
I also tried copying from the PDF of the spec (adjusting quotes as necessary) - same result.

When I execute the page I end up with a standard 500 error
Root cause:
java.lang.ClassCastException: java.io.StringReader
org.apache.jsp.tagVariableTest_jsp._jspService(tagVariableTest_jsp.java:62)

Line62 of the generated JSP turns out to be:
var1 = (java.lang.String) _jspx_page_context.findAttribute("var1");

Ok, I can understand ClassCastException - it thinks that var1 should be a String, and the actual attribute is a StringReader. But why is it a StringReader? Where did the variable get created? And why is it attempting to do this assignment at all?

Can someone please point me in the right direction?
What is wrong with the code/setup?
Is this a known issue? I googled for it but couldn't seem to find anything.

Thanks,
evnafets


Editing with resolution:
The ClassCastException was being caused by the line in the tag:

<jsp:invoke fragment="frag" varReader="var1"/>

As mentioned here the varReader attribute specifies the attribute to store the evaluation result as a StringReader. The exception was caused by Tomcat generated code trying to retrieve the value of "var1" and cast it to a String. As a String is not a StringReader so, it raised an exception at that point.

I'm not sure if the coding error is they should have used the "var" instead of the "varReader" attribute, or they shouldn't have used either and just evaluated it as is.
Removing that attribute completely prints out the fragment, and then the body both with the value of "var1":

Fragment Template Text 30.
Invoke the body: Body of tag that defines an AT_BEGIN scripting variable 30

Making the attribute var="var1" executes the fragment, and stores the result to var1. The body is then evaluated with this new value of var1 resulting in:

Invoke the body: Body of tag that defines an AT_BEGIN scripting variable Fragment Template Text 30

Personally I think the first case makes more sense, but this code is presented as an example of the innerworkings, not best practice.
I still would have expected the example to compile/run in any case. I was fairly surprised when it didn't.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

居里长安 2024-07-21 12:45:39

语法参考中,您可以看到 var 或 varReader 是

用于存储片段调用结果的作用域属性的名称

因此我担心示例代码包含错误。 如果您需要将 jsp:invoke 的结果直接写入页面,则无需将其分配给 var。

您可以尝试省略“varReader”属性吗?

From the syntax reference you can see that either var or varReader is

The name of a scoped attribute to store the result of the fragment invocation in

So I am afraid the sample code contains an error. If you need to write the result of jsp:invoke directly to the page you do not need to assign it to a var.

Can you try leaving out the "varReader" attribute?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文