📄 jspadvanced8.html
字号:
</p><a name="wp72598"> </a><p class="pBody">If the body of the tag needs to be evaluated, the <code class="cCode">doStartTag</code> method needs to return <code class="cCode">EVAL_BODY_BUFFERED</code>; otherwise, it should return <code class="cCode">SKIP_BODY</code>.</p><a name="wp72599"> </a><p class="pDefinitionTerm">doInitBody Method</p><a name="wp72601"> </a><p class="pBody">The <code class="cCode">doInitBody</code> method is called after the body content is set but before it is evaluated. You generally use this method to perform any initialization that depends on the body content.</p><a name="wp72603"> </a><p class="pDefinitionTerm">doAfterBody Method</p><a name="wp72604"> </a><p class="pBody">The <code class="cCode">doAfterBody</code> method is called <em class="cEmphasis">after</em> the body content is evaluated. <code class="cCode">doAfterBody</code> must return an indication of whether to continue evaluating the body. Thus, if the body should be evaluated again, as would be the case if you were implementing an iteration tag, <code class="cCode">doAfterBody</code> should return <code class="cCode">EVAL_BODY_AGAIN</code>; otherwise, <code class="cCode">doAfterBody</code> should return <code class="cCode">SKIP_BODY</code>.</p><a name="wp72606"> </a><p class="pBody">The following example reads the content of the body (which contains a SQL query) and passes it to an object that executes the query. Since the body does not need to be reevaluated, <code class="cCode">doAfterBody</code> returns <code class="cCode">SKIP_BODY</code>.</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public class QueryTag extends BodyTagSupport { public int doAfterBody() throws JspTagException { BodyContent bc = getBodyContent(); // get the bc as string String query = bc.getString(); // clean up bc.clearBody(); try { Statement stmt = connection.createStatement(); result = stmt.executeQuery(query); } catch (SQLException e) { throw new JspTagException("QueryTag: " + e.getMessage()); } return SKIP_BODY; }}<a name="wp72607"> </a></pre></div><a name="wp72609"> </a><p class="pDefinitionTerm">release Method</p><a name="wp72610"> </a><p class="pBody">A tag handler should reset its state and release any private resources in the <code class="cCode">release</code> method.</p><a name="wp73416"> </a><h3 class="pHeading2">Cooperating Tags</h3><a name="wp72788"> </a><p class="pBody">Tags cooperate by sharing objects. JSP technology supports two styles of object sharing.</p><a name="wp72789"> </a><p class="pBody">The first style requires that a shared object be named and stored in the page context (one of the implicit objects accessible to both JSP pages and tag handlers). To access objects created and named by another tag, a tag handler uses the <code class="cCode">pageContext.getAttribute(name,</code> <code class="cCode">scope)</code> method.</p><a name="wp72790"> </a><p class="pBody">In the second style of object sharing, an object created by the enclosing tag handler of a group of nested tags is available to all inner tag handlers. This form of object sharing has the advantage that it uses a private namespace for the objects, thus reducing the potential for naming conflicts.</p><a name="wp72791"> </a><p class="pBody">To access an object created by an enclosing tag, a tag handler must first obtain its enclosing tag with the static method <code class="cCode">TagSupport.findAncestorWithClass(from,</code> <code class="cCode">class)</code> or the <code class="cCode">TagSupport.getParent</code> method. The former method should be used when a specific nesting of tag handlers cannot be guaranteed. Once the ancestor has been retrieved, a tag handler can access any statically or dynamically created objects. Statically created objects are members of the parent. Private objects can also be created dynamically. Such objects can be stored in a tag handler with the <code class="cCode">setValue</code> method and retrieved with the <code class="cCode">getValue</code> method.</p><a name="wp72792"> </a><p class="pBody">The following example illustrates a tag handler that supports both the named and private object approaches to sharing objects. In the example, the handler for a query tag checks whether an attribute named <code class="cCode">connectionId</code> has been set. If the <code class="cCode">connection</code> attribute has been set, the handler retrieves the connection object from the page context. Otherwise, the tag handler first retrieves the tag handler for the enclosing tag, and then retrieves the connection object from that handler.</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public class QueryTag extends BodyTagSupport { public int doStartTag() throws JspException { String cid = getConnectionId(); Connection connection; if (cid != null) { // there is a connection id, use it connection =(Connection)pageContext. getAttribute(cid); } else { ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, ConnectionTag.class); if (ancestorTag == null) { throw new JspTagException("A query without a connection attribute must be nested within a connection tag."); } connection = ancestorTag.getConnection(); ... } }}<a name="wp72793"> </a></pre></div><a name="wp72794"> </a><p class="pBody">The query tag implemented by this tag handler could be used in either of the following ways:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><tt:connection cid="con01" ... > ... </tt:connection><tt:query id="balances" connectionId="con01"> SELECT account, balance FROM acct_table where customer_number = ? <tt:param value="${requestScope.custNumber}" /></tt:query><tt:connection ... > <tt:query cid="balances"> SELECT account, balance FROM acct_table where customer_number = ? <tt:param value="${requestScope.custNumber}" /> </tt:query></tt:connection><a name="wp72795"> </a></pre></div><a name="wp72796"> </a><p class="pBody">The TLD for the tag handler indicates that the <code class="cCode">connectionId</code> attribute is optional with the following declaration:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><tag> ... <attribute> <name>connectionId</name> <required>false</required> </attribute></tag><a name="wp72797"> </a></pre></div><a name="wp73424"> </a><h3 class="pHeading2">Tags That Define Variables</h3><a name="wp74661"> </a><p class="pBody">The mechanisms for defining EL variables in classic tags are similar to those described in Chapter <a href="JSPTags.html#wp74641">15</a><a href="JSPTags.html#wp74644"></a>. You must declare the variable in a <code class="cCode">variable</code> element of the TLD or in a tag extra info class. You use PageContext().setAttribute(name, value) or <code class="cCode">PageContext.setAttribute(name,</code> <code class="cCode">value,</code> <code class="cCode">scope)</code> methods in the tag handler to create or update an association between a name accessible in the page context and the object that is the value of the variable. For classic tag handlers, <a href="JSPAdvanced8.html#wp74617">Table 16-3</a> illustrates how the availability of a variable affects when you may want to set or update the variable's value.</p><div align="left"><table border="1" summary="Scripting Variable Availability" id="wp74617"> <caption><a name="wp74617"> </a><div class="pTableTitle">Table 16-3 Scripting Variable Availability </div></caption> <tr align="center"> <th><a name="wp74623"> </a><div class="pCellHeading">Value</div></th> <th><a name="wp74625"> </a><div class="pCellHeading">Availability</div></th> <th><a name="wp74627"> </a><div class="pCellHeading">In Methods</div></th></tr> <tr align="left"> <td><a name="wp74629"> </a><div class="pCellBody"><code class="cCode">NESTED</code></div></td> <td><a name="wp74631"> </a><div class="pCellBody">Between the start tag and the end tag</div></td> <td><a name="wp74633"> </a><div class="pCellBody"><code class="cCode">doStartTag</code>, <code class="cCode">doInitBody</code>, and <code class="cCode">doAfterBody</code>.</div></td></tr> <tr align="left"> <td><a name="wp74635"> </a><div class="pCellBody"><code class="cCode">AT_BEGIN</code></div></td> <td><a name="wp74637"> </a><div class="pCellBody">From the start tag until the end of the page</div></td> <td><a name="wp74639"> </a><div class="pCellBody"><code class="cCode">doStartTag</code>, <code class="cCode">doInitBody</code>, <code class="cCode">doAfterBody</code>, and <code class="cCode">doEndTag</code>.</div></td></tr> <tr align="left"> <td><a name="wp74641"> </a><div class="pCellBody"><code class="cCode">AT_END</code></div></td> <td><a name="wp74643"> </a><div class="pCellBody">After the end tag until the end of the page</div></td> <td><a name="wp74645"> </a><div class="pCellBody"><code class="cCode">doEndTag</code></div></td></tr></table></div><p class="pBody"></p><a name="wp74646"> </a><p class="pBody">An EL variable defined by a custom tag can also be accessed in a scripting expression. For example, the Web service described in the previous section could be encapsulated in a custom tag that returns the response in an EL variable named by the <code class="cCode">var</code> attribute and then <code class="cCode">var</code> could be accessed in a scripting expression as follows:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><ws:hello var="response" name="<%=request.getParameter("username")%>" /><h2><font color="black"><%= response %>!</font></h2><a name="wp73371"> </a></pre></div><a name="wp73372"> </a><p class="pBody">Remember that in situations where scripting is not allowed</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp73373"> </a><div class="pSmartList1"><li>In a tag body where the <code class="cCode">body-content</code> is declared as <code class="cCode">scriptless</code></li></div><a name="wp73374"> </a><div class="pSmartList1"><li>In a page where scripting is specified to be invalid</li></div></ul></div><a name="wp73375"> </a><p class="pBody">you wouldn't be able to access the EL variable in a scriptlet or expression. Instead, you would have to use the JSP expression language to access the variable.</p> </blockquote> <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider"> <table width="550" summary="layout" id="SummaryNotReq1"> <tr> <td align="left" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/download.html#tutorial" target="_blank">Download</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/faq.html" target="_blank">FAQ</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/history.html" target="_blank">History</a> </td> <td align="center" valign="center"><a accesskey="p" href="JSPAdvanced7.html"><img id="LongDescNotReq1" src="images/PrevArrow.gif" width="26" height="26" border="0" alt="Prev" /></a><a accesskey="c" href="J2EETutorialFront.html"><img id="LongDescNotReq1" src="images/UpArrow.gif" width="26" height="26" border="0" alt="Home" /></a><a accesskey="n" href="WebI18N.html"><img id="LongDescNotReq3" src="images/NextArrow.gif" width="26" height="26" border="0" alt="Next" /></a><a accesskey="i" href="J2EETutorialIX.html"></a> </td> <td align="right" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/docs/api/index.html" target="_blank">API</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/search.html" target="_blank">Search</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/sendusmail.html" target="_blank">Feedback</a></font> </font> </td> </tr> </table> <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider"><p><font size="-1">All of the material in <em>The J2EE(TM) 1.4 Tutorial</em> is <a href="J2EETutorialFront2.html">copyright</a>-protected and may not be published in other workswithout express written permission from Sun Microsystems.</font> </body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -