📄 package-summary.html
字号:
container (via generated code). The setter methods used to setthe properties are discovered using the JavaBeans introspectormachinery.<p> The protocol supported by a tag handler provides for passing ofparameters, the evaluation and reevaluation of the body of the action,and for getting access to objects and other tag handlers in theJSP page.<p> A tag handler instance is responsible for processing one requestat a time. It is the responsability of the JSP container to enforcethis.<p> Additional translation time information associated with the actionindicates the name of any scripting variables it may introduce, theirtypes and their scope. At specific moments, the JSP container willautomatically synchronize the <A HREF="../../../../javax/servlet/jsp/PageContext.html" title="class in javax.servlet.jsp"><CODE>PageContext</CODE></A> information with variablesin the scripting language so they can be made available directlythrough the scripting elements.<h3>Properties</h3><p> A tag handler has some properties. All tag handlers have a<em>pageContext</em> property for the JSP page where the tag islocated, and a <em>parent</em> property for the tag handler to theclosest enclosing action. Specific tag handler classes may haveadditional properties.<p> All attributes of a custom action must be JavaBeans componentproperties, although some properties may not be exposed as attributes.The attributes that are visible to the JSP translator are exactlythose listed in the Tag Library Descriptor (TLD).<p> All properties of a tag handler instance exposed as attributeswill be initialized by the container using the appropriate settermethods before the instance can be used to perform the action methods.It is the responsibility of the JSP container to invoke theappropriate setter methods to initialize these properties. It is theresponsability of user code, be it scriptlets, JavaBeans code, or codeinside custom tags, to not invoke these setter methods, as doingotherwise would interfere with the container knowledge.<p> The setter methods that should be used when assigning a value toan attribute of a custom action are determined by using the JavaBeansintrospector on the tag handler class, then use the setter methodassociated with the property that has the same name as the attributein question. An implication (unclear in the JavaBeans specification)is that there is only one setter per property.<p> Unspecified attributes/properties should not be set (using asetter method).<p> Once properly set, all properties are expected to be persistent,so that if the JSP container ascertains that a property has alreadybeen set on a given tag handler instance, it must not set itagain. <p> The JSP container may reuse classic tag handler instances for multipleoccurrences of the corresponding custom action, in the same page or indifferent pages, but only if the same set of attributes are used for alloccurrences. If a tag handler is used for more than one occurence, thecontainer must reset all attributes where the values differ between thecustom action occurrences. Attributes with the same value in alloccurrences must not be reset. If an attribute value is set as arequest-time attribute value (using a scripting or an EL expression),the container must reset the attribute between all reuses of the taghandler instance. <p> User code can access property information and access and modifytag handler internal state starting with the first action method (doStartTag)up until the last action method (doEndTag or doFinally for tag handlersimplementing TryCatchFinally).<h3>Tag Handler as a Container-Managed Object</h3><p> Since a tag handler is a container managed object, the containerneeds to maintain its references; specifically, user code should notkeep references to a tag handler except between the start of the firstaction method (doStartTag()) and the end of the last action method(doEndTag() or doFinally() for those tags that implement TryCatchFinally).<p> The restrictions on references to tag handler objects andon modifying attribute properties gives the JSP container substantialfreedom in effectively managing tag handler objects to achieve differentgoals. For example, a container may implementing different pooling strategiesto minimize creation cost, or may hoist setting of properties to reducecost when a tag handler is inside another iterative tag. <h3>Conversions</h3><p>A tag handler implements an action; the JSP container must followthe type conversions described in Section 2.13.2 when assigning valuesto the attributes of an action.<h3>Empty and Non-Empty Actions</h3>An empty action has no body; it may use one of two syntaxes: either<foo/> or <foo></foo>. Since empty actions have nobody the methods related to body manipulation are not invoked.There is a mechanism in the Tag Library Descriptor to indicatethat a tag can only be used to write empty actions; when used,non-empty actions using that tag will produce a translation error.<p>A non-empty action has a body. <a name="tag interface"><h3>The Tag Interface</h3></a> <p> A Tag handler that does not want to process its body can implementjust the Tag interface. A tag handler may not want to process itsbody because it is an empty tag or because the body is just tobe "passed through".<p> The Tag interface includes methods to provide page contextinformation to the Tag Handler instance, methods to handle thelife-cycle of tag handlers, and two main methods for performingactions on a tag: <code>doStartTag()</code> and<code>doEndTag()</code>. The method <code>doStartTag()</code> isinvoked when encountering the start tag and its return value indicateswhether the body (if there is any) should be skipped, or evaluated andpassed through to the current response stream. The method<code>doEndTag()</code> is invoked when encountering the end tag; itsreturn value indicates whether the rest of the page should continue tobe evaluated or not.<p> If an exception is encountered during the evaluation of thebody of a tag, its doEndTag method will not be evaluated. See theTryCatchFinally tag for methods that are guaranteed to be evaluated.<a name="iterationtag interface"><h3>The IterationTag Interface</h3></a> <p> The IterationTag interface is used to repeatedly reevaluatethe body of a custom action. The interface has one method:<code>doAfterBody()</code> which is invoked after each evaluationof the body to determine whether to reevaluate or not.<p> Reevaluation is requested with the value 2, which in JSP 1.1 isdefined to be BodyTag.EVAL_BODY_TAG. That constant value is stillkept in JSP 1.2 (for full backwards compatibility) but, to improveclarity, a new name is also available: IterationTag.EVAL_BODY_AGAIN.To stop iterating, the returned value should be 0, which isTag.SKIP_BODY.<h3>The JspIdConsumer Interface</h3>This interface indicates to the container that a tag handler wishes to be provided with a compiler generated ID that is uniquewithin the page.<h3>The TagSupport Base Class</h3><p> The TagSupport class is a base class that can be used whenimplementing the Tag or IterationTag interfaces.<a name="bodycontent"><h2>2. Tag Handlers that want Access to their Body Content</h2></a><p>The evaluation of a body is delivered into a <code>BodyContent</code>object. This is then made available to tag handlers that implementthe <code>BodyTag</code> interface. The <code>BodyTagSupport</code>class provides a useful base class to simplify writing these handlers.<p> If a Tag handler wants to have access to the content of its bodythen it must implement the <code>BodyTag</code> interface.This interface extends IterationTag, provides two additional methods<code>setBodyContent(BodyContent)</code> and<code>doInitBody()</code>and refers to an object of type BodyContent.<p> A BodyContent is a subclass of <code>JspWriter</code> that has afew additional methods to convert its contents into a String, insertthe contents into another JspWriter, to get a Reader into itscontents, and to clear the contents. Its semantics also assure thatbuffer size will never be exceeded.<p> The JSP page implementation will create a BodyContent if thedoStartTag() method returns a EVAL_BODY_BUFFERED. This object will bepassed to doInitBody(); then the body of the tag will be evaluated,and <em>during that evaluation <b>out</b> will be bound to theBodyContent just passed to the BodyTag handler</em>. ThendoAfterBody() will be evaluated. If that method returns SKIP_BODY, nomore evaluations of the body will be done; if the method returnsEVAL_BODY_AGAIN, then the body will be evaluated, and doAfterBody() willbe invoked again.<p> The content of a BodyContent instance remains available until afterthe invocation of its associated doEndTag() method.<p> A common use of the BodyContent is to extract its contents into aString and then use the String as a value for some operation. Anothercommon use is to take its contents and push it into the out Streamthat was valid when the start tag was encountered (that is availablefrom the PageContext object passed to the handler in setPageContext).<a name="dynamic"><h2>3. Dynamic Attributes</h2></a><p>Any tag handler can optionally extend the <code>DynamicAttributes</code>interface to indicate that it supports dynamic attributes. In addition to implementing the <code>DynamicAttributes</code> interface, tag handlers that support dynamic attributes must declare that they do so in the Tag Library Descriptor.</p><p>The TLD is what ultimately determines whether a tag handler accepts dynamic attributes or not. If a tag handler declares that it supports dynamic attributes in the TLD but it does not implement the <code>DynamicAttributes</code> interface, the tag handler must be considered invalid by the container.</p><p>If the dynamic-attributes element for a tag being invoked contains the value "true", the following requirements apply:</p><ul> <li>For each attribute specified in the tag invocation that does not have a corresponding attribute element in the TLD for this tag, a call must be made to <code>setDynamicAttribute()</code>, passing in the namespace of the attribute (or null if the attribute does not have a namespace or prefix), the name of the attribute without the namespace prefix, and the final value of the attribute.</li> <li>Dynamic attributes must be considered to accept request-time expression values as well as deferred expressions.</li> <li>Dynamic attributes must be treated as though they were of type <code>java.lang.Object</code>. If a <code>ValueExpression</code> is passed as a dynamic attribute, the default value for the expected return type is assumed to be <code>java.lang.Object</code>. If a <code>MethodExpression</code> is passed as a dynamic attribute, the default method signature is assumed to be <code>void method()</code>.</li> <li>Note that passing a String literal as a dynamic attribute will never be considered as a deferred expression.</li> <li>The JSP container must recognize dynamic attributes that are passed to the tag handler using the <jsp:attribute> standard action.</li> <li>If the <code>setDynamicAttribute()</code> method throws <code>JspException</code>, the <code>doStartTag()</code> or <code>doTag()</code> method is not invoked for this tag, and the exception must be treated in the same manner as if it came from a regular attribute setter method.</li> <li>For a JSP document in either standard or XML syntax, If a dynamic attribute has a prefix that doesn't map to a namespace, a translation error must occur. In standard syntax, only namespaces defined using taglib directives are recognized.</li></ul><p>In the following example, assume attributes a and b are declared using the attribute element in the TLD, attributes d1 and d2 are not declared, and the dynamic-attributes element is set to "true". The attributes are set using the calls:<ul> <li><code>setA( "1" )</code>, </li> <li><code>setDynamicAttribute( null, "d1", "2" )</code>, </li> <li><code>setDynamicAttribute( "http://www.foo.com/jsp/taglib/mytag.tld", "d2", "3" )</code>, </li> <li><code>setB( "4" )</code>, </li> <li><code>setDynamicAttribute( null, "d3", "5" )</code>, and</li> <li><code>setDynamicAttribute( "http://www.foo.com/jsp/taglib/mytag.tld", "d4", "6" )</code>.</li></ul><pre><jsp:root xmlns:mytag="http://www.foo.com/jsp/taglib/mytag.tld" version="2.0"> <mytag:invokeDynamic a="1" d1="2" mytag:d2="3"> <jsp:attribute name="b">4</jsp:attribute> <jsp:attribute name="d3">5</jsp:attribute> <jsp:attribute name="mytag:d4">6</jsp:attribute> </mytag:invokeDynamic></jsp:root></pre><a name="thmgmt"><h2>4. Annotated Tag Handler Management Example</h2></a>Below is a somewhat complete example of the way one JSP containercould choose to do some tag handler management. There are manyother strategies that could be followed, with different pay offs.<p>In this example, we are assuming thatx:iterate is an iterative tag, while x:doit and x:foobar are simpletag. We will also assume that x:iterate and x:foobar implement theTryCatchFinally interface, while x:doit does not.<pre><x:iterate src="foo"> <x:doit att1="one" att2="<%= 1 + 1 %>" /> <x:foobar /> <x:doit att1="one" att2="<%= 2 + 2 %>" /></x:iterate><x:doit att1="one" att2="<%= 3 + 3 %>" /></pre><p> The particular code shown below assumes there is some pool of taghandlers that are managed (details not described, although poolmanaging is simpler when there are no optional attributes), andattemps to reuse tag handlers if possible. The code also "hoists" setting of properties to reduce the cost when appropriate, e.g. insidean iteration.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -