JSP标签生命周期

发布于 2024-07-14 12:28:23 字数 319 浏览 9 评论 0原文

我刚刚在我的代码中引入了一个错误,因为我似乎误解了 jsp 标签的生命周期。

在出现错误之前,标签的工作方式如下: 我将一些集合作为属性传递给标签,并将其显示为表格。 该集合从控制器传递到 JSP 中。

出现错误后: 我删除了设置集合的属性。 相反,在标签中,我检查集合是否为空,然后通过请求中的名称获取它(使用命名约定)。

让我没想到的是: 在标签中最初设置集合后,它在后续执行中永远不会变为空! 它仍然被定义为 TLD 中的非必需属性。

预计标签在执行之间不会保留以前的值。

I just introduced a bug into my code because I seem to have misunderstood the jsp tag lifecycle.

The tag worked like this before the bug:
I pass the tag some collection as an attribute, and it displays it as a table. The collection was passed into the JSP from the controller.

After the bug:
I removed the attribute which set the collection. Instead, in the tag I check if the collection is null, and then grab it by name from the request (using a naming convention).

The thing that I didn't expect:
after the collection was initially set in the tag, it would never become null on subsequent executions! It was still defined as a non-requred attribute in the TLD.

I expected the tag to not hold on to previous values between executions.

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

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

发布评论

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

评论(6

踏雪无痕 2024-07-21 12:28:23

您自己回答了这个问题 - 它是汇总的。 请参阅标记教程,了解在 java 实现中要实现的内容,以及从那里链接的页面,包含调用序列

ATag t = new ATag();
t.setPageContext(...);
t.setParent(...);
t.setAttribute1(value1);
t.setAttribute2(value2);
t.doStartTag();
t.doEndTag();
t.release();

也就是说,根据 API 的要求,在 doEndTag() 中重新初始化您的标签实例。 (根据 Julien Kronegg 的评论进行了更改,谢谢)

请注意,池化可能依赖于容器,但很合法(并且,由于 API 设置,可能在任何地方都可以完成)。

You answered the question yourself - it's pooled. See the tag tutorial for what to implement in java implementations, together with the page linked from there, containing the invocation sequence:

ATag t = new ATag();
t.setPageContext(...);
t.setParent(...);
t.setAttribute1(value1);
t.setAttribute2(value2);
t.doStartTag();
t.doEndTag();
t.release();

That is, re-initialize your tag instance in doEndTag() as the API requires. (changed as of comment by Julien Kronegg, thanks)

Note that pooling probably is container dependent, but well legal (and, due to the API setup, probably done everywhere).

意中人 2024-07-21 12:28:23

简短的回答:
您不应该自己写入属性。 通过这样做,您就可以将清洁状态作为您的责任。

对于更长的答案,JSP 2.0 规范规定了以下内容(第 2-51 页) :

  • 为标记的特定出现的所有指定属性调用设置器
  • 省略属性调用设置器(保留默认值不变,并且,在您的情况下,内部状态中的非法值)
  • 标记处理程序只能由具有同一组指定属性的事件重用

这三点共同保证属性属性始终正确初始化,同时仍然保留默认值(在构造函数中定义)或属性声明)。 作为回报,它仅在只有容器操纵属性属性(通过调用设置器)的假设下起作用。

为了完整起见:

  • 不应使用 release() 在标签处理程序调用之间重置内部状态。 它仅保证在 GC 之前被调用,并且应用于释放长期资源。
  • 如果您想在doStartTag()中初始化实例变量,请注意不要覆盖属性,因为此时容器已经调用了setter。
  • doEndTag() 应该可以安全地用于初始化,因为在发生异常时标签不应该被重用(参见第 2-54 页 [2])

The short answer:
You are not supposed to write to attribute properties yourself. By doing so, you make cleaning the state your responsibility.

For a longer answer, the JSP 2.0 Spec dictates the following (page 2-51):

  • Setters get called for all specified attributes of a specific occurrence of a tag
  • Setters are not called for omitted attributes (leaving default values intact and, in your case, an illegal value in the internal state)
  • Tag handlers may only be reused by occurrences with the same set of specified attributes

These three points together guarantee that attribute properties are always correctly initialized, while still retaining default values (defined in a constructor or a properties' declaration). In return, it only works on the assumption that only the container manipulates attribute properties (by calling the setters).

For the sake of completeness:

  • release() should not be used to reset internal state between calls of a tag handler. It is only guaranteed to be called before GC and should be used to free long-term resources.
  • If you want to initialize instance variables in doStartTag(), be careful not to overwrite attributes, because the setters have already been called by the container at this point.
  • doEndTag() should be safe to use for initialization because tags should never be reused in case of an exception (see page 2-54 [2])
病毒体 2024-07-21 12:28:23

JSP 1.2 规范添加了 TryCatchFinally 接口。
http://docs.oracle.com/javaee /1.4/api/javax/servlet/jsp/tagext/TryCatchFinally.html

所以看起来你应该在 doStartTag() 方法中分配资源并在 doFinally() 方法中进行清理。

The JSP 1.2 specification added the TryCatchFinally interface.
http://docs.oracle.com/javaee/1.4/api/javax/servlet/jsp/tagext/TryCatchFinally.html

So it looks like you should allocate resources in the doStartTag() method and cleanup in the doFinally() method.

踏雪无痕 2024-07-21 12:28:23

所以答案是:
该标签被汇集到神奇的池土地中,并在执行之间重复使用。 标签规范说:

“不应设置未指定的属性/属性(使用 setter 方法)。”

so the answer is:
the tag gets pooled into magical pool land, and is reused between executions. the tag spec says:

"Unspecified attributes/properties should not be set (using a setter method)."

鲜肉鲜肉永远不皱 2024-07-21 12:28:23

对 Tomcat 6 的观察表明,release() 仅在容器关闭时才被调用。 标记处理程序实例成员应在 doEndTag() 中清除实例状态。 来自 API 文档:

“必须重置与此实例关联的所有实例状态。”

请参阅 TagSupport.doEndTag ()

Observation of Tomcat 6 suggests release() is only invoked when the container is shutting down. Tag handler instance members should clear instance state in doEndTag(). From the api doc:

"All instance state associated with this instance must be reset."

see TagSupport.doEndTag()

欲拥i 2024-07-21 12:28:23

释放方法是JSP使用完标签的时间段,用于允许标签释放。

the release method is the period of time when JSP has finished using the tag and is used to allow the tag to release.

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