JSP标签生命周期
我刚刚在我的代码中引入了一个错误,因为我似乎误解了 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您自己回答了这个问题 - 它是汇总的。 请参阅标记教程,了解在 java 实现中要实现的内容,以及从那里链接的页面,包含调用序列:
也就是说,根据 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:
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).
简短的回答:
您不应该自己写入属性。 通过这样做,您就可以将清洁状态作为您的责任。
对于更长的答案,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):
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.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])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.
所以答案是:
该标签被汇集到神奇的池土地中,并在执行之间重复使用。 标签规范说:
“不应设置未指定的属性/属性(使用 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)."
对 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()
释放方法是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.