Download FAQ History |  | API Search Feedback

> ## Programming Simple Tag Handlers

> The classes and interfaces used to implement simple tag handlers are contained in the `javax.servlet.jsp.tagext` package. Simple tag handlers implement the `SimpleTag` interface. Interfaces can be used to take an existing Java object and make it a tag handler. For most newly created handlers, you would use the `SimpleTagSupport` classes as a base class.

> The heart of a simple tag handler is a single method--`doTag`--which gets invoked when the end element of the tag is encountered. Note that the default implementation of the `doTag` method of `SimpleTagSupport` does nothing.

> A tag handler has access to an API that allows it to communicate with the JSP page. The entry point to the API is the JSP context object (`javax.servlet.jsp.JspContext)`. `JspContext` provides access to implicit objects. `PageContext` extends `JspContext` with servlet-specific behavior. A tag handler can retrieve all the other implicit objects (request, session, and application) accessible from a JSP page through these objects. If the tag is nested, a tag handler also has access to the handler (called the parent) associated with the enclosing tag.

> #### Packaging Tag Handlers

> Tag handlers can be made available to a Web application in two basic ways. The classes implementing the tag handlers can be stored in an unpacked form in the `WEB-INF/classes/` subdirectory of the Web application. Alternatively, if the library is distributed as a JAR, it is stored in the `WEB-INF/lib/` directory of the Web application.

> #### How Is a Simple Tag Handler Invoked?

> The `SimpleTag` interface defines the basic protocol between a simple tag handler and a JSP page's servlet. The JSP page's servlet invokes the `setJspContext`, `setParent`, and attribute setting methods before calling `doStartTag`.

>     ATag t = new ATag();
>     t.setJSPContext(...);
>     t.setParent(...);
>     t.setAttribute1(value1);
>     t.setAttribute2(value2);
>     ...
>     t.setJspBody(new JspFragment(...))
>     t.doTag();

> The following sections describe the methods that you need to develop for each type of tag introduced in Types of Tags.

> ### Basic Tags

> The handler for a basic tag without a body must implement the `doTag` method of the `SimpleTag` interface. The `doTag` method is invoked when the start tag is encountered.

> The basic tag discussed in the first section,

>     <tt:basic />

> would be implemented by the following tag handler:

>     public HelloWorldSimpleTag extends SimpleTagSupport {
>       public void doTag() throws JspException, IOException {
>         getJspContext().getOut().write("Hello, world.");
>       }
>     }

> ### Tags with Attributes

> #### Defining Attributes in a Tag Handler

> For each tag attribute, you must define a set method in the tag handler that conforms to the JavaBeans architecture conventions. For example, the tag handler for the JSTL `c:if` tag,

>     <c:if test="${Clear}">

> contains the following method:

>     public void setTest(boolean test) {
>       this.test = test;
>     }

> #### Attribute Validation

> The documentation for a tag library should describe valid values for tag attributes. When a JSP page is translated, a Web container will enforce any constraints contained in the TLD element for each attribute.

> The attributes passed to a tag can also be validated at translation time with the `validate` method of a class derived from `TagExtraInfo`. This class is also used to provide information about variables defined by the tag (see TagExtraInfo Class).

> The `validate` method is passed the attribute information in a `TagData` object, which contains attribute-value tuples for each of the tag's attributes. Since the validation occurs at translation time, the value of an attribute that is computed at request time will be set to `TagData.REQUEST_TIME_VALUE`.

> The tag `<tt:twa` `attr1="value1"/>` has the following TLD `attribute` element:

>     <attribute>
>       <name>attr1</name>
>       <required>true</required>
>       <rtexprvalue>true</rtexprvalue>
>     </attribute>

> This declaration indicates that the value of `attr1` can be determined at runtime.

> The following `validate` method checks that the value of `attr1` is a valid Boolean value. Note that since the value of `attr1` can be computed at runtime, `validate` must check whether the tag user has chosen to provide a runtime value.

>     public class TwaTEI extends TagExtraInfo {
>       public ValidationMessage[] validate(TagData data) {
>         Object o = data.getAttribute("attr1");
>         if (o != null && o != TagData.REQUEST_TIME_VALUE) {
>           if (((String)o).toLowerCase().equals("true") ||
>             ((String)o).toLowerCase().equals("false") )
>             return null;
>           else
>             return new ValidationMessage(data.getId(),
>               "Invalid boolean value.");
>         }
>         else
>           return null;
>       }
>     }

> #### Dynamic Attributes

> Tag handlers that support dynamic attributes must declare that they do so in the `tag` element of the TLD (see Declaring Tag Handlers). In addition, your tag handler must implement the `setDynamicAttribute` method of the `DynamicAttributes` interface. For each attribute specified in the tag invocation that does not have a corresponding `attribute` element in the TLD, the Web container calls `setDynamicAttribute`, passing in the namespace of the attribute (or null if in the default namespace), the name of the attribute, and the value of the attribute. You must implement the `setDynamicAttribute` method to remember the names and values of the dynamic attributes so that they can be used later on when `doTag` is executed. If the `setDynamicAttribute` method an exception, the `doTag` method is not invoked for the tag, and the exception must be treated in the same manner as if it came from an attribute setter method.

> The following implementation of `setDynamicAttribute` saves the attribute names and values in lists. Then, in the `doTag` method, the names and values are echoed to the response in an HTML list.

>       private ArrayList keys = new ArrayList();
>       private ArrayList values = new ArrayList();

>       public void setDynamicAttribute(String uri,
>         String localName, Object value ) throws JspException {
>         keys.add( localName );
>         values.add( value );
>     }

>     public void doTag() throws JspException, IOException {
>       JspWriter out = getJspContext().getOut();
>       for( int i = 0; i < keys.size(); i++ ) {
>           String key = (String)keys.get( i );
>           Object value = values.get( i );
>           out.println( "<li>" + key + " = " + value + "</li>" );
>       }
>     }

> ### Tags with Bodies

> A tag handler for a tag with a body is implemented differently depending on whether or not the tag handler needs to manipulate the body. A tag handler manipulates the body when it reads or modifies the contents of the body.

> ##### Tag Handler Does Not Manipulate the Body

> If a tag handler needs to simply evaluate the body, it gets the body with the `getJspBody` method of `SimpleTag` and then evaluates the body with the `invoke` method.

> The following tag handler accepts a `test` parameter and evaluates the body of the tag if the test evaluates to true. The body of the tag is encapsulated in a JSP fragment. If the test is true, the handler retrieves the fragment with the `getJspBody` method. The `invoke` method directs all output to a supplied writer or to the `JspWriter` returned by the `getOut` method of the `JspContext` associated with the tag handler if the writer is `null`.

>     public class IfSimpleTag extends SimpleTagSupport {
>       private boolean test;
>       public void setTest(boolean test) {
>         this.test = test;
>       }
>       public void doTag() throws JspException, IOException {
>         if(test){
>           getJspBody().invoke(null);
>         }
>       }
>     }

> ##### Tag Handler Manipulates the Body

> If the tag handler needs to manipulate the body, the tag handler must capture the body in a `StringWriter`. The `invoke` method directs all output to a supplied writer. Then the modified body is written to the `JspWriter` returned by the `getOut` method of the `JspContext`. Thus, a tag that converts its body to upper case could be written as follows:

>     public class SimpleWriter extends SimpleTagSupport {
>       public void doTag() throws JspException, IOException {
>         StringWriter sw = new StringWriter();
>         jspBody.invoke(sw);
>         jspContext().
>           getOut().println(sw.toString().toUpperCase());
>       }
>     }

> ### Tags That Define Variables

> Similar communication mechanisms exist for communication between JSP page and tag handlers as for JSP pages and tag files.

> To emulate `IN` parameters, use tag attributes. A tag attribute is communicated between the calling page and the tag handler when the tag is invoked. No further communication occurs between the calling page and tag handler.

> To emulate `OUT` or nested parameters, use variables with availability `AT_BEGIN`, `AT_END`, or `NESTED`. The variable is not initialized by the calling page, but set by the tag handler.

> For `AT_BEGIN` availability, the variable is available in the calling page from the start tag until the scope of any enclosing tag. If there's no enclosing tag, then the variable is available to the end of the page. For `AT_END` availability, the variable is available in the calling page after the end tag until the scope of any enclosing tag. If there's no enclosing tag, then the variable is available to the end of the page. For nested parameters, the variable is available in the calling page between the start tag and the end tag.

> When you develop a tag handler you are responsible for creating and setting the object referenced by the variable into a context accessible from the page. You do this by using the JspContext().setAttribute(name, value) or `JspContext.setAttribute(name,` `value,` `scope)` method. You retrieve the page context with the `getJspContext` method of `SimpleTag`.

> Typically, an attribute passed to the custom tag specifies the name of the variable and the value of the variable is dependent on another attribute. For example, the `iterator` tag retrieves the name of the variable from the `var` attribute and determines the value of the variable from a computation performed on the `group` attribute.

>     public void doTag() throws JspException, IOException {
>       if (iterator == null)
>         return;
>       while (iterator.hasNext()) {
>         getJspContext().setAttribute(var, iterator.next());
>         getJspBody().invoke(null);
>       }
>     }
>     public void setVar(String var) {
>       this.var = var;
>     }
>     public void setGroup(Collection group) {
>       this.group = group;
>       if(group.size() > 0)
>         iterator = group.iterator();
>     }

> The scope that an variable can have is summarized in Table 18-13. The scope constrains the accessibility and lifetime of the object.

> Table 18-13 Scope of Objects
> Name | Accessible From | Lifetime
> --- | --- | ---
> `page` | Current page | Until the response has been sent back to the user or the request is passed to a new page
> `request` | Current page and any included or forwarded pages | Until the response has been sent back to the user
> `session` | Current request and any subsequent request from the same browser (subject to session lifetime) | The life of the user's session
> `application` | Current and any future request in the same Web application | The life of the application

> ##### TagExtraInfo Class

> In Declaring Tag Variables for Tag Handlers we discussed how to provide information about tag variable in the tag library descriptor. Here we describe another approach: defining a tag extra info class. You define a tag extra info class by extending the class `javax.servlet.jsp.tagext.TagExtraInfo`. A `TagExtraInfo` must implement the `getVariableInfo` method to return an array of `VariableInfo` objects containing the following information:

> - Variable name
> - Variable class
> - Whether the variable refers to a new object
> - The availability of the variable

> The Web container passes a parameter of type `javax.servlet.jsp.tagext.TagData` to the `getVariableInfo` method that contains attribute-value tuples for each of the tag's attributes. These attributes can be used to provide the `VariableInfo` object with an EL variable's name and class.

> The following example demonstrates how to provide information about the variable created by the `iterator` tag in a tag extra info class. Since the name (`var`) and class (`type`) of the variable are passed in as tag attributes, they can be retrieved with the `data.getAttributeString` method and used to fill in the `VariableInfo` constructor. To allow the variable `var` to be used only within the tag body, the scope of the object is set to be `NESTED`.

>     package iterator;
>     public class IteratorTei extends TagExtraInfo {
>       public VariableInfo[] getVariableInfo(TagData data) {
>         String type = data.getAttributeString("type");
>         if (type == null)
>           type = "java.lang.Object";
>         return new VariableInfo[] {
>           new VariableInfo(data.getAttributeString("var"),
>           type,
>           true,
>           VariableInfo.NESTED)
>         };
>       }
>     }

> The fully qualified name of the tag extra info class defined for an EL variable must be declared in the TLD in the `tei-class` subelement of the `tag` element. Thus, the `tei-class` element for `IteratorTei` would be as follows:

>     <tei-class>
>       iterator.IteratorTei
>     </tei-class>

> ### Cooperating Tags

> Tags cooperate by sharing objects. JSP technology supports two styles of object sharing.

> 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 `pageContext.getAttribute(name,` `scope)` method.

> 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.

> To access an object created by an enclosing tag, a tag handler must first obtain its enclosing tag with the static method `SimpleTagSupport.findAncestorWithClass(from,` `class)` or the `SimpleTagSupport.getParent` 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 `setValue` method and retrieved with the `getValue` method.

> 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 `connectionId` has been set. If the `connectionId` 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.

>     public class QueryTag extends SimpleTagSupport {
>       public int doTag() 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();
>           ...
>         }
>       }
>     }

> The query tag implemented by this tag handler could be used in either of the following ways:

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

> The TLD for the tag handler indicates that the `connectionId` attribute is optional with the following declaration:

>     <tag>
>       ...
>       <attribute>
>         <name>connectionId</name>
>         <required>false</required>
>       </attribute>
>     </tag>

> ### Examples

> The custom tags described in this section demonstrate solutions to two recurring problems in developing JSP applications: minimizing the amount of Java programming in JSP pages and ensuring a common look and feel across applications. In doing so, they illustrate many of the styles of tags discussed in the first part of the chapter.

> #### An Iteration Tag

> Constructing page content that is dependent on dynamically generated data often requires the use of flow control scripting statements. By moving the flow control logic to tag handlers, flow control tags reduce the amount of scripting needed in JSP pages.

> The `iterator` tag retrieves objects from a collection stored in a JavaBeans component and assigns them to an EL variable. This tag is a very simplified example of the an iterator tag. Web applications requiring such functionality should use the JSTL `forEach` tag, which is discussed in Iterator Tags. The body of the tag retrieves information from the variable. While elements remain in the collection, the `iterator` tag causes the body to be reevaluated.

> ##### JSP Page

> The `index.jsp` page invokes the `iterator` tag to iterate through a collection of department names. Each item in the collection is assigned to the `departmentName` variable.

>     <%@ taglib uri="/tlt" prefix="tlt" %>
>     <html>
>       <head>
>       <title>Departments</title>
>       </head>
>       <body bgcolor="white">
>       <jsp:useBean id="myorg" class="myorg.Organization"/>
>       <table border=2 cellspacing=3 cellpadding=3>
>         <tr>
>           <td><b>Departments</b></td>
>         </tr>
>       <tlt:iterator var="departmentName" type="java.lang.String"
>           group="${myorg.departmentNames}">
>         <tr>
>           <td><a href="list.jsp?deptName=${departmentName}">
>             ${departmentName}</a></td>
>         </tr>
>       </tlt:iterator>
>       </table>
>       </body>
>     </html>

> ##### Tag Handler

> The tag handler passes the current element of the group back to the page in an EL variable called `var`, which is accessed using the expression language in the calling page. After the variable is set, the body is evaluated with the `invoke` method.

>     public void doTag() throws JspException, IOException {
>       if (iterator == null)
>         return;
>       while (iterator.hasNext()) {
>         getJspContext().setAttribute(var, iterator.next());
>         getJspBody().invoke(null);
>       }
>     }
>     public void setVar(String var) {
>       this.var = var;
>     }
>     public void setGroup(Collection group) {
>       this.group = group;
>       if(group.size() > 0)
>         iterator = group.iterator();
>     }

> #### A Template Tag Library

> A template provides a way to separate the common elements that are part of each screen from the elements that change with each screen of an application. Putting all the common elements together into one file makes it easier to maintain and enforce a consistent look and feel in all the screens. It also makes development of individual screens easier because the designer can focus on portions of a screen that are specific to that screen while the template takes care of the common portions.

> The template is a JSP page with placeholders for the parts that need to change with each screen. Each of these placeholders is referred to as a parameter of the template. For example, a simple template could include a title parameter for the top of the generated screen and a body parameter to refer to a JSP page for the custom content of the screen.

> The template uses a set of nested tags--`definition`, `screen`, and `parameter`--to define a table of screen definitions and uses an `insert` tag to insert parameters from a screen definition into a specific application screen.

> ##### JSP Pages

> The template for the Duke's Bookstore example, `template.jsp`, is shown below. This page includes a JSP page that creates the screen definition and then uses the `insert` tag to insert parameters from the definition into the application screen.

>     <%@ taglib uri="/tutorial-template" prefix="tt" %>
>     <%@ page errorPage="/template/errorinclude.jsp" %>
>     <%@ include file="/template/screendefinitions.jsp" %>
>     <html>
>     <head>
>     <title>
>     <tt:insert definition="bookstore" parameter="title"/>
>     </title>
>     </head>
>     <body  bgcolor="#FFFFFF">
>       <tt:insert definition="bookstore" parameter="banner"/>
>     <tt:insert definition="bookstore" parameter="body"/>
>     <center><em>Copyright &copy; 2002 Sun Microsystems, Inc. </
>     em></center>
>     </body>
>     </html>

> `screendefinitions.jsp` creates a screen definition based on a request attribute `selectedScreen`:

>     <tt:definition name="bookstore"
>     screen="${requestScope
>       ['javax.servlet.forward.servlet_path']}">
>       <tt:screen id="/bookstore">
>       <tt:parameter name="title" value="Duke's Bookstore"
>         direct="true"/>
>       <tt:parameter name="banner" value="/template/banner.jsp"
>         direct="false"/>
>       <tt:parameter name="body" value="/bookstore.jsp"
>         direct="false"/>
>       </tt:screen>
>       <tt:screen id="/bookcatalog">
>       <tt:parameter name="title" direct="true">
>           <jsp:attribute name="value" >
>             <fmt:message key="TitleBookCatalog"/>
>           </jsp:attribute>
>         </tt:parameter>
>         <tt:parameter name="banner" value="/template/banner.jsp"
>         direct="false"/>
>         <tt:parameter name="body" value="/bookcatalog.jsp"
>         direct="false"/>
>       </tt:screen>
>       ...
>     </tt:definition>

> The template is instantiated by the `Dispatcher` servlet. `Dispatcher` first gets the requested screen and stores it as an attribute of the request. This is necessary because when the request is forwarded to `template.jsp`, the request URL doesn't contain the original request (for example, `/bookstore3/catalog`) but instead reflects the path (`/bookstore3/template.jsp`) of the forwarded page. Then `Dispatcher` performs business logic based on the request URL, which updates model objects. Finally, the servlet dispatches the request to `template.jsp`:

>     public class Dispatcher extends HttpServlet {
>       public void doGet(HttpServletRequest request,
>         HttpServletResponse response) {
>         String bookId = null;
>         BookDetails book = null;
>         String clear = null;
>         BookDBAO bookDBAO =
>           (BookDBAO)getServletContext().
>             getAttribute("bookDBAO");
>         HttpSession session = request.getSession();
>         String selectedScreen = request.getServletPath();
>         ShoppingCart cart = (ShoppingCart)session.
>           getAttribute("cart");
>         if (cart == null) {
>           cart = new ShoppingCart();
>           session.setAttribute("cart", cart);
>         }
>         request.setAttribute("selectedScreen",
>           request.getServletPath());
>         if (selectedScreen.equals("/bookcatalog")) {
>           bookId = request.getParameter("Add");
>           if (!bookId.equals("")) {
>             try {
>               book = bookDBAO.getBookDetails(bookId);
>               if ( book.getOnSale() ) {
>                 double sale = book.getPrice() * .85;
>                 Float salePrice = new Float(sale);
>                 book.setPrice(salePrice.floatValue());
>               }
>               cart.add(bookId, book);
>             } catch (BookNotFoundException ex) {
>               // not possible
>             }
>           }
>         } else if (selectedScreen.equals("/bookshowcart")) {
>           bookId =request.getParameter("Remove");
>           if (bookId != null) {
>             cart.remove(bookId);
>           }
>           clear = request.getParameter("Clear");
>           if (clear != null && clear.equals("clear")) {
>             cart.clear();
>           }
>         } else if (selectedScreen.equals("/bookreceipt")) {
>         // Update the inventory
>           try {
>             bookDBAO.buyBooks(cart);
>           } catch (OrderException ex) {
>             request.setAttribute("selectedScreen",
>               "/bookOrderError");
>           }
>         }
>         try {
>           request.
>             getRequestDispatcher(
>             "/template/template.jsp").
>             forward(request, response);
>         } catch(Exception ex) {
>           ex.printStackTrace();
>         }
>       }

>       public void doPost(HttpServletRequest request,
>         HttpServletResponse response) {
>         request.setAttribute("selectedScreen",
>           request.getServletPath());
>         try {
>           request.
>             getRequestDispatcher(
>             "/template/template.jsp").
>             forward(request, response);
>         } catch(Exception ex) {
>           ex.printStackTrace();
>         }
>       }
>     }

> ##### Tag Handlers

> The template tag library contains four tag handlers--`DefinitionTag`, `ScreenTag`, `ParameterTag`, and `InsertTag`--that demonstrate the use of cooperating tags. `DefinitionTag`, `ScreenTag`, and `ParameterTag` comprise a set of nested tag handlers that share private objects. `DefinitionTag` creates a public object named `bookstore` that is used by `InsertTag`.

> In `doTag`, `DefinitionTag` creates a private object named `screens` that contains a hash table of screen definitions. A screen definition consists of a screen identifier and a set of parameters associated with the screen. These parameters are loaded when the body of the definition tag, which contains nested `screen` and `parameter` tags, is invoked. `DefinitionTag` creates a public object of class `Definition`, selects a screen definition from the `screens` object based on the URL passed in the request, and uses it to initialize a public `Definition` object.

>     public int doTag() {
>       try {
>         screens = new HashMap();
>         getJspBody().invoke(null);
>         Definition definition = new Definition();
>         PageContext context = (PageContext)getJspContext();
>         ArrayList params = (ArrayList) screens.get(screenId);
>         Iterator ir = null;
>         if (params != null) {
>           ir = params.iterator();
>           while (ir.hasNext())
>             definition.setParam((Parameter)ir.next());
>         // put the definition in the page context
>         context.setAttribute(definitionName, definition,
>           context.APPLICATION_SCOPE);
>         }
>       }

> The table of screen definitions is filled in by `ScreenTag` and `ParameterTag` from text provided as attributes to these tags. Table 18-14 shows the contents of the screen definitions hash table for the Duke's Bookstore application

> Table 18-14 Screen Definitions
> Screen Id | Title | Banner | Body
> --- | --- | --- | ---
> `/bookstore` | `Duke's Bookstore` | `/banner.jsp` | `/bookstore.jsp`
> `/bookcatalog` | `Book Catalog` | `/banner.jsp` | `/bookcatalog.jsp`
> `/bookdetails` | `Book Description` | `/banner.jsp` | `/bookdetails.jsp`
> `/bookshowcart` | `Shopping Cart` | `/banner.jsp` | `/bookshowcart.jsp`
> `/bookcashier` | `Cashier` | `/banner.jsp` | `/bookcashier.jsp`
> `/bookreceipt` | `Receipt` | `/banner.jsp` | `/bookreceipt.jsp`

> .

> If the URL passed in the request is /`bookstore`, the `Definition` contains the items from the first row of Table 18-14:

> Table 18-15 Definition for URL /bookstore
> Title | Banner | Body
> --- | --- | ---
> `Duke's Bookstore` | `/banner.jsp` | `/bookstore.jsp`

> The parameters for the URL `/bookstore` are shown in Table 18-16. The parameters specify that the value of the `title` parameter, Duke's Bookstore, should be inserted directly into the output stream, but the values of `banner` and `body` should be dynamically included.

> Table 18-16 Parameters for the URL /bookstore
> Parameter Name | Parameter Value | isDirect
> --- | --- | ---
> `title` | `Duke's Bookstore` | `true`
> `banner` | `/banner.jsp` | `false`
> `body` | `/bookstore.jsp` | `false`

> `InsertTag` inserts parameters of the screen definition into the response. In the `doTag` method, it retrieves the definition object from the page context and then inserts the parameter value. If the parameter is direct, it is directly inserted into the response; otherwise, the request is sent to the parameter, and the response is dynamically included into the overall response.

>     public void doTag() throws JspTagException {
>       Definition definition = null;
>       Parameter parameter = null;
>       boolean directInclude = false;
>       PageContext context = (PageContext)getJspContext();

>         // get the definition from the page context
>       definition = (Definition)context.getAttribute(
>         definitionName, context.APPLICATION_SCOPE);
>         // get the parameter
>       if (parameterName != null && definition != null)
>         parameter = (Parameter)
>           definition.getParam(parameterName);

>       if (parameter != null)
>         directInclude = parameter.isDirect();

>       try {
>         // if parameter is direct, print to out
>         if (directInclude && parameter  != null)
>           context.getOut().print(parameter.getValue());
>         // if parameter is indirect,
>             include results of dispatching to page
>         else {
>           if ((parameter != null) &&
>             (parameter.getValue() !=  null))
>           context.include(parameter.getValue());
>         }
>       } catch (Exception ex) {
>           throw new JspTagException(ex.getMessage());
>       }
>     }

Download FAQ History |  | API Search Feedback

All of the material in The Java(TM) Web Services Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.