C H A P T E R  4

Developing Your Own Web Application

This chapter provides an overview of how to program web modules using the IDE. This high-level view ties together the tasks involved in creating your application. It then provides some details on individual programming tasks.

See Chapter 5 for a description of the process of configuring, executing, debugging, and deploying a web application.

It is recommended that you work through the Forte for Java 4, Community Edition Tutorial before building your own web application with the Forte for Java 4 IDE.


Development Work Flow

This section provides an overview of the work flow typically involved in developing a web module using the IDE. When developing a new web application, it often makes sense to proceed in an iterative fashion. The list below describes the major development tasks. Each task refers to a section later in the chapter that provides more detailed information. The IDE's online help for the JSP/Servlet module also provides information on these tasks.

To develop a web module using the IDE:

1. Create a web module. For details, see Creating a Web Module.

2. Create the web components you plan to use. This process might include:

The servlets, filters, beans, and utility classes go in the /WEB-INF/classes directory of the web module. However, if the classes are packaged as JAR files, they go in the /WEB-INF/lib directory.
The IDE supplies templates for all these objects in the New wizard. Templates are also provided for simple and advanced filters and four kinds of listeners. Each other object has a single template. See "Creating a New File" in the Core IDE online help for details.
The recommended process is to develop your tag library in place within the web module in which you want to use it. Then when you are finished developing the tags, move the tag library source files to a separate filesystem for maintenance. At this point, package the library as a JAR file and place it in the lib directory of the web module containing the dependent JSP pages. See Developing Your Own Tag Libraries for details.

3. Configure the web module and its components by editing the deployment descriptor file. See Configuring the Web Module Deployment Descriptor for details.


Web Modules in the IDE

A web module is a J2EE deployment construct. When you develop web applications using the IDE, it creates the necessary web module structure for you. By enforcing the web module structure, the IDE ensures that web modules can be packaged for delivery. It also ensures that they contain the deployment descriptor information (the web.xml file) required for deployment on servlet containers. Moreover, the Java Servlet 2.3 Specification and JSP 1.2 Specification require that JSP pages be executed inside a web module.



Note - To execute or debug JSP pages and servlets in the IDE, you need to put them into a web module. Both JSP pages and servlets must be executed from within a web module. This behavior differs from some earlier versions of the IDE.



A J2EE web module corresponds to a "web application" as defined in the Java Servlet Specification version 2.3. In the IDE, a construct called a web module group can be used to deploy several web modules together. See "Creating a Web Module Group" and "Executing Web Modules" in the JSP/Servlet online help for more information.

A web module is the smallest deployable and usable unit of web resources in a J2EE application. It corresponds to the servlet context, as defined in the J2EE specification. Web modules are typically packaged and deployed as web archive (WAR) files. However, depending on the web server you use, web modules might not have to be packaged in order to be deployed. The format of a WAR file is identical to that of a JAR file. However, the contents and use of WAR files differ from JAR files, so WAR file names use a .war extension.

Web modules use a hierarchical structure for storing their resources. This structure is represented at development time as a filesystem mounted at the web module root directory with the following folders:

Creating a Web Module

The first step in creating a web application is creating a new web module. Use the New wizard to create a web module in the designated filesystem. Then the web module's root directory node appears in the Explorer. When you expand the node, the web module structure is reflected in the node contents:

The web module directory structure is treated as an object within the IDE's Explorer window. It is displayed within a filesystem mounted at the web module's root directory. For instance, a web module object type has attributes you can set in its Properties window and a set of pertinent commands available in its contextual menu. The web module object is represented by the icon for the WEB-INF directory:WEB-INF icon.

Furthermore, like any other object type in the Explorer, a web module can be created from a template.



Note - You mount a web module in the Explorer exactly as you would mount any other filesystem. See "Mounting a Filesystem" in the Core IDE Help Set for information on mounting filesystems. However, you must mount the web module at its root directory, which is the directory containing the WEB-INF directory. If you mount a directory containing a web module, rather than the web module itself, the web module is not properly recognized. In this situation, when the web module root is a subdirectory of a mounted filesystem, you cannot perform some operations usually associated with a web module. These operations might include the execution or deployment of your web module or its components.



Importing an Existing Web Module

The IDE enables you to continue development on web modules that have been created externally. To import an existing web module, you can use one of two methods, depending on how the web module is delivered:

Indicate the location of the desired web module in the Mount Filesystem dialog box. It is also possible for you to mount a CVS filesystem containing a web module.

For details, see "Mounting an Existing Web Module" in the JSP/Servlet online help.

To be mounted in the IDE, your web module must conform to the structured directory format or the web archive format (WAR). The formats are described in the Java Servlet 2.3 specification.

Before executing an imported WAR file, you must first unpack and mount it as a web module. Unpack and mount a WAR file from the Filesystems tab of the Explorer. Mount the directory containing the relevant WAR file, if you haven't already done so. Right-click the icon for the desired WAR file. Then choose Unpack as Web Module from the contextual menu. In the Unpack WAR Folder dialog box, specify the directory where you want the unpacked files to be stored. Click Unpack Here. The WAR file is unpacked in the specified directory. The directory is mounted and appears as a web module in the Filesystems tab of the Explorer. If the WAR file contains no Java source files, then any servlets and JavaBeans components are not editable once the WAR file is unpacked.

For details, see "Unpacking and Mounting a WAR File" in the JSP/Servlet online help.


Creating JSP Pages

JSP pages are used in web applications to present information to end users and to enable data from end users to flow back to the server. An example would be data presentation and modification through the use of forms.

JSP files are created and managed in the IDE in a similar way to other file types. To execute a JSP page, you must place it within a properly mounted web module.

You can create a JSP page in one of two ways:

You can create JSP pages in the root directory of your web module or within a subdirectory of this root directory

JSP pages placed in the WEB-INF directory or any of its subdirectories are not directly accessible from a client browser. However, they are accessible as resources from a servlet. This feature is often used in conjunction with a Front Controller design pattern. It is used to control access to JSP pages that need to be displayed in a specific order. It is also used to control access based on security constraints. An example of JSP pages requiring controlled access might be pages in the middle of a checkout procedure. For more on the Front Controller design pattern, see Front Controllers and Using the Servlet as a Front Controller.

You can work with .dwt files, Dreamweaver version 3.0 and earlier. In addition to generating a a JSP page from a .dwt template, the IDE enables you to open and edit .dwt files in the Source Editor. You can also configure the IDE to open .dwt templates in an editor of your choice

Using page Directives

You can use page directives to specify global declarative information about a JSP page that is unrelated to any particular request. For example, use directives to:

For details on page directive syntax, see Directive Elements.

Creating and Invalidating Sessions

If a session does not already exist, executing the JSP page creates one. Any additional session-related pages continue to use that session until it is invalidated. Invalidation can occur either through a time-out or an explicit call. You can use the call below within a JSP scriptlet:

session.invalidate();

You can also invalidate the session from within a servlet using the following code:

request.getSession().invalidate();

For more information on HTTP sessions, see HTTP Sessions.

Modifying the JSP File

The IDE offers support for JSP syntax, including code completion for JSP tags. For example, you can press Ctrl-Spacebar to show the code completion box. For details on code completion, see "Completing an HTML Tag" in the Core IDE online help.

Editing JSP source code is similar to editing HTML. Hence, the IDE provides support for both HTML and JSP tags. For details, see "Editing a JSP or Servlet Source File" in the JSP/Servlet online help.

When executing a web module with modified JSP pages, the IDE saves and recompiles the JSP files as they are accessed. See "Executing JSP and Servlet Source Files" in the online help for additional information.

What Is a Scriptlet?

A scriptlet is a scripting element that enables you to enter valid Java code into a JSP page. Variables and methods declared in a declaration element are available to other scriptlets in the same JSP page. For more information on scripting elements, see Scripting Elements.

When to Use Scriptlets

In the past, many JSP development guides have focused on using scriptlets. It is now recommended that you avoid using scriptlets. They make JSP pages more difficult to understand and maintain. Typically, the content developers who might be creating and modifying the JSP pages are unaccustomed to Java code. Hence, they might use tools that would ruin the scriptlet code. Sometimes Java code is necessary to perform processing within the JSP file. An example would be the formatting of a table or the presentation of a large amount of information in chunks. In these circumstances, consider using custom tag library features. See Using Existing Tag Libraries. You can also create View Creation Helper beans with properties accessible with JSP tags. See View Creation Helpers and Using Additional Classes or Beans for more information.

The use of scriptlets can be beneficial in limited circumstances and is fully supported by the IDE. An example is creating early prototypes of new features you later plan to encapsulate in a bean or tag handler.

Working With JSP Includes

To make it easier to create complex pages from modular components, JSP pages can include other pages. These pages could include JSP pages and HTML or XML files. You can use either the <jsp:include> action or the <%@include%> directive to subsume these pages. For details on the JSP life cycle, including translation and runtime, see JSP Page Life Cycle. For an example of how to include a Composite View in your JSP page, see Creating a Composite View Template.

Using the <jsp:include> Action

When you use JSP include actions in your code, the complete page using the included files is built at request time. A JSP page using included actions has its own implementation class. It cannot affect the processing of the remainder of the page or alter the HTTP headers of the response. Use the <jsp:include> action for pages whose dynamic content is likely to change after the translation of the containing JSP file. You should also use the <jsp:include> action when you do not know which page to include until request time. This usage is recommended because the page attribute can be set by an expression, for example:

<jsp:include page="<%= dynamicPageName %>" flush="true">

Here is an example of including a file with the action:

<jsp:include page="/foo.jsp"/>

Using the <%@include%> Directive

When you provide JSP includes using a directive, they are included at translation time in the implementation class of the containing JSP file. They can affect the remainder of the page and alter the HTTP headers of the response. Use the <%@include%> directive to include pages that are static and unlikely to change.

Here is an example of including a file with the directive:

<%@include file="bar.html"%>

Creating a Composite View Template

The following code sample creates a template JSP page using the include action within embedded HTML tables. The header, footer, and navigation bar cells always include the same JSP files (that is, header.jsp, footer.jsp, and navbar.jsp). The main cell includes the content JSP file, which is passed to the template using the usePage attribute.

<table width="100%" border="0" cellspacing="0" cellpadding="0">
<colgroup span="2">
<col width="140">
<col>
</colgroup>
  <tr> 
    <td colspan="2">
     <jsp:include page="header.jsp" flush="true"/> 
    </td>
  </tr>
  <tr> 
    <td align="left" valign="top" bgcolor="#dddddd">
      <jsp:include page="navbar.jsp" flush="true"/>
    </td>
    <td align="left" valign="top">
       <table width="100%" cellpadding="10px" border="0">
        <tr><td>
        <jsp:include page="<%= usePage%>" flush="true"/>
        </font></td></tr>
       </table>
    </td>
  </tr>
  <tr> 
    <td colspan="2">
      <jsp:include page="footer.jsp" flush="true"/>
    </td>
  </tr>
</table>

Typically, a template declares the start and the end of two items:

  • The HTML document
  • The table that defines the overall grid layout

It's a good practice to design included files to describe a complete HTML element, with both a start tag and an end tag (if an end tag is required).

Another approach is to use specially designed template tags. You can find an example of template tags in the Struts framework. For details, see the Template Tags section of the Struts User Guide at: http://jakarta.apache.org/struts/userGuide/struts-template.html

Using Additional Classes or Beans

Use beans in your web module to gain access to external resources such as a database or flat files, that is, plain text files that might contain data. Additional utility classes can perform Java functions through methods accessible from servlets, beans, or JSP scriptlets.

The IDE provides a template for the creation of beans within your web application. In the New wizard, click the Beans category and select the Java Bean item. See "Creating a File" in the Core IDE online help for more information.

To specify beans used by your JSP page, you can use the <jsp:useBean> action. To get and set properties, respectively, on your beans, you can use the <jsp:getProperty> and <jsp:setProperty> actions.

To populate all the values of the bean from values in the JSP file, use the setProperty action with an * in the property attribute and remove the value attribute. The names of the properties in the bean must match the names of the request parameters. Each of the request parameters typically corresponds to an element of an HTML form.

Beware that if a property value is empty, the attribute is left unchanged in the bean. An example is when the user left a field blank, or cleared out the value. If this situation is a possibility, explicitly set each value by name, as shown in the example below. Do not use the *.

Here is an example of using a bean in your JSP page:

<jsp:useBean id="myFoo" scope="session" class="com.sun.FooBean"/>

Here is an example of using a bean and setting a property.

<jsp:useBean id="myBar" scope="page" class="com.sun.BarBean">
<jsp:setProperty id="myBar" property="blah" value="0"/>
</jsp:useBean>

Here is an example of getting a property:

<jsp:getProperty id="myFoo" property="fooProp"/>


Creating Servlets

To add a servlet to your web application, create a package in the WEB-INF/Classes directory within the web module. Then create a new servlet within this package. You should always create servlets within the WEB-INF/classes directory of your web module. This directory is included in the IDE's internal classpath when the web module is mounted in the Explorer.

When you create a servlet with the New wizard, the IDE enables you to configure deployment entries for the new servlet. Use the Deployment Configuration panel of the wizard to perform this task. A servlet created outside the IDE can be added to your web application. However, the servlet does not just execute on its own. You must add the servlet to the deployment descriptor file to coordinate it with other web resources within the web module. For additional information, see "Creating a JSP or Servlet Source File" in the JSP/Servlet online help.

As provided in the IDE for other Java classes and for JSP pages, code completion is available for servlets. Use code completion to remind yourself of available methods and values. See "Editing a JSP or Servlet Source File" in the online help for details.

You can compile the servlet from contextual menus in the Source Editor or from its node in the Explorer. With the servlet open in the Source Editor, press the F9 button to compile. If you create a servlet outside the IDE, it is treated as an ordinary Java class. For servlet features to be available, you must instruct the IDE to treat this class as a servlet. For details, see "Adding an Existing Servlet to a Web Module" in the online help.

Declaring the Servlet in the Deployment Descriptor

When you are creating reusable servlets, the deployment descriptor entry is helpful. It contains data that can be changed at deployment time without recompiling the servlet code. You can define initialization parameters to adapt the functioning of your servlet to a particular deployment situation. For example, you could specify currency, date, and time formats in init parameters for your servlet.

Servlets are not available to the application unless you declare them. As described above, this declaration is part of the process when you create servlets with the New wizard. However, you must add declarations to the deployment descriptor for servlets brought into your web module any other way.

Servlet Entries

A servlet entry contains either the name of the class that implements the servlet, or a path to the JSP page. It also contains a unique name that identifies it within the web application.

Servlet Mappings

For the servlet to be accessible and to receive requests, one or more servlet mappings must accompany the servlet entry. You can also map JSP pages. However, unlike servlets, JSP pages can process requests even if you do not map them. Servlet mappings match a named servlet or a JSP page to a URL pattern. The servlet or JSP page is activated if a specific condition is met. The portion of the request URI following the server identifier and the context path must match the URL pattern string. The context path is the path associated with the web module when it was deployed to the server. The URL pattern can be a definite string, or it can contain wildcard characters. A URL mapping of /catalog/* matches any request path beginning with /catalog/.

Load on Startup

The servlet container can initialize resources at any time unless a servlet or JSP page is specified as "loaded on startup."

When a servlet is loaded at startup, the servlet is instantiated and its init() method is called when the container starts the web application. Similarly, when a JSP page is loaded on startup, it is compiled and initialized during startup. The JSP page is also compiled and initialized any time later, if it is changed.

When a servlet is loaded on startup, it can set up resources that are used by multiple resources. For example, a servlet could add a parameter to the servlet context. Configuring the servlet to be loaded on startup guarantees the parameter is available when other resources try to access it. If the value of load on startup is negative or not set, then the container is free to load the servlet at will. If the value is a positive integer, then the container initializes the servlet on startup. The container also loads servlets with lower values before servlets with higher values.

Adding a Servlet Entry

To add a servlet to your deployment descriptor, right-click your web.xml file, and choose Properties. In the Deployment pane of the Properties window, select Servlets. In the Servlet Property Editor, you can add, edit, or delete servlet entries. See "Servlets Property Editor" in the JSP/Servlet online help for details.

Displaying and Changing Servlet Entries

To display or alter deployment descriptor entries for a selected servlet, choose Properties from the servlet's contextual menu. Then click the Deployment Entries field to edit servlet properties.

Modifying the Servlet

Modify your servlet in the IDE the same way you would proceed with any other Java class. Changes to servlets or deployment descriptors in web modules already executed from the IDE require you to re-execute the web module. Choose Execute (Force Reload) from the contextual menu of your servlet or the WEB-INF node. This action restarts the server before executing the servlet. Your servlet is then saved and recompiled when executing using the IDE.

Servlet-Generated HTTP Responses

A servlet can write to an HTTP response. This simple example of outputting HTML from a servlet is taken from the processRequest method of the IDE's servlet template in the New wizard.

java.io.PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("Hello, World!");
out.println("</body>");
out.println("</html>");
out.close();
CODE EXAMPLE 4-1 Outputting HTML From a Servlet
response.serContentType("text/html");

It is not required that a servlet output HTML. Instead, a servlet can be used to modify the HTTPRequest and HTTPResponse objects. For example, the Front Controller servlet forwards the request to another servlet or JSP file, which then writes to the response object.

Using the Servlet as a Front Controller

To construct a Front Controller:

1. Create a new servlet using the IDE's servlet template. From the main menu bar's File menu, choose New, then JSP & Servlets, then Servlet.

2. On the Deployment Configuration panel of the New Servlet wizard, specify a URL pattern that matches the request URLs you want to capture. For example, specify /ShowProducts/*.

The servlet container attempts to match request paths to servlets in two cases. The match is attempted when the container first receives the request. It is attempted again if the request is redispatched internally through a forward or an include. You cannot map a servlet that forwards to another resource using the path /*. This mapping would cause a recursive call to your servlet.

3. Once the servlet is created, insert processing code into the processRequest method to forward the request to the appropriate page. For instance, the following code sample shows how the request below might be handled:

http://my.company.com/ShowProducts?product=stuffedbear
protected void processRequest(HttpServletRequest request, 												HttpServletResponse response)
    throws ServletException, java.io.IOException {
        String sendTo;
        if (request.getQueryString().equals("product=stuffedbear")) 
            sendTo = "/WEB-INF/showStuffedBearInfo.jsp";
        else sendTo = "/WEB-INF/noProductSpecified.jsp";
            
RequestDispatcher sendPage =  getServletContext()												.getRequestDispatcher (sendTo);
sendPage.forward(request, response);}

In this case, the Front Controller servlet ShowProducts would use the query string product=stuffedbear to select the appropriate view. The view might consist of a product description page for the stuffed bear. The Front Controller servlet would then forward the request to that JSP page.

Use the Front Controller servlet to direct page flow when the application, rather than the user, controls the order in which pages are accessed. An example of this situation would be a set of pages that implements the checkout process. While purchasing products in a shopping cart, the user shouldn't be able to bookmark or return to any of the checkout pages without going through each step in the sequence. To implement this scenario, you would place the checkout JSP pages inside the WEB-INF directory of the web module. This location is not directly accessible by requests from a browser. It is only accessible though another resource that uses the RequestDispatcher API to serve those pages. This situation is shown in the previous example code. In this example, you can control how the pages are obtained and used by creating a Front Controller servlet. The Front Controller processes the input during the checkout process, and then determines what page to show the user next.

See Front Controllers for more information on the Front Controller design pattern.

Using Additional Classes or Beans

Servlets can obtain and use additional classes and beans in the same manner as any other Java class. The IDE facilitates the creation of beans using the New wizard. For more information, see "Creating a New File" in the Core IDE online help.


Creating Filters

You can create and add a filter to your web application using the New wizard. This method is same one used to create a JSP file or a servlet. As with servlets, you use a checkbox in the New wizard to generate deployment descriptor elements with default settings. See "Creating a Filter" in the JSP/Servlet online help for more information.

Declaring the Filter in the Deployment Descriptor

To declare your filter, use the Filters element in the deployment descriptor to define:

  • A filter name, used to map the filter to a servlet or URL
  • A filter class, used by the container to identify the filter type
  • Initialization parameters for the filter, which are called init-params

You can also define:

  • Large and small icons
  • A textual description
  • A display name for tool manipulation

For details see, "Adding a Filter to the Deployment Descriptor" and "Filters Property Editor" in the JSP/Servlet online help.

In order for filters to be available within a web application, you must declare them within the deployment descriptor. A filter entry contains the name of the class (filter-class) implementing the filter. In addition, the entry contains a unique name identifying it inside the web application. You can also specify initialization parameters for the filter. Similar to mapping a servlet, you must add one or more mappings for a filter to receive requests.

When the servlet container receives a request for the web application, it constructs a filter chain. The chain consists of all filters whose URL mappings match the request URI and the context path in the order the filters appear in the deployment descriptor. The context path is the path associated with the web module when it was deployed to the server. The filters in the chain are activated when the request enters the container. Unlike servlets, no filter chain is constructed for internal dispatches. Hence, you can map a filter to /* to have it called for every request coming into the container.

To configure a filter or a collection of filters for activation, specify deployment descriptor Filter Mapping elements. Map filters to a particular servlet by the servlet's logical name by mapping a filter to the URL pattern. You use the same technique to map filters to a group of servlets and static content resources.

The Filter Mappings element shows the number of filter mappings defined for the web module. Filter mappings specify the URL patterns that should be processed by a particular filter. To specify additional filter mappings, use the Filter Mappings Property Editor. See "Editing Web Module Deployment Properties" and "Filter Mappings Property Editor" in the JSP/Servlet online help for details.

Processing HTTP Requests and Responses

You can use filters to modify an HTTP request or an HTTP response. Filters can be used for authentication. For instance, when a JSP file or servlet is requested, the filter can determine whether an end user is permitted to view the desired web component. The end user's name can be located in the session information. If the name is blank, the filter routes the request to a login page. If the name is not blank, but has no authorization to view a page, a different outcome transpires. The filter routes the request to a page explaining the required authorization. You can also use a filter to create log entries each time a response is sent to a particular client. The entries are based on information from the request and the session.

For an example, see the SignOnFilter class, which is part of the Java Pet Store, at:

http://java.sun.com/blueprints/code/jps13/src/


Using Tag Libraries

As previously described, a tag library consists of a set of tag handler classes that implements the tag library's feature set and a Tag Library Descriptor (TLD) file that describes the tags in the library and maps each tag to a tag handler. You can extend the standard set of actions by creating your own custom actions and tags. By doing so, you can modularize and encapsulate functional units of code within your application and make the code more reusable. With proper design, you can cleanly separate logic from formatting. This separation should enable you to eliminate the use of Java code embedded in your JSP pages.

The IDE supports:

Using Existing Tag Libraries

The IDE provides the JSP Tag Library Repository to facilitate the management of existing custom tag libraries. Initially, the JSP Tag Library Repository includes the JSTL (JavaServer Pages Standard Tag Library) 1.0 from the Apache Jakarta group.

You can add tag libraries that you have created or downloaded from external sources to the JSP Tag Library Repository. Choose the JSP Tag Library Repository from the Tools menu. Use the JSP Tag Library dialog box that is displayed to add tag libraries to the repository.

Adding a Tag Library to a Web Module

In order to use a tag library in your application, you must first add it to your web module.

From the contextual menu of the WEB-INF node of your web module, choose Add JSP Tag Library. You can find the tag library either in the Tag Library Repository or in the filesystem. Some tag libraries are delivered as a single JAR file. Other tag libraries might contain additional dependent JAR files.

If you choose standard from the JSP Tag Library Repository, then all tag libraries that are part of the JSTL are added to the WEB-INF/lib directory. For more information about the JSTL, see JSP Standard Tag Library.

Using Tag Libraries From External Sources

To add and use a tag library from external sources in a JSP file, add its associated JAR file to the JSP Tag Library Repository. The repository enables you to store tag libraries so you can add them to web modules. The placement of other custom tag libraries in the repository makes them readily available for addition to web modules.

From the main menu bar's Tools menu, choose Add Tag Library to Repository. In the JSP Tag Library Repository dialog box, click Add to locate the desired library.

For more information, see "Adding a Custom Tag Library to the Repository" in the online help.

Tag Library Descriptors

A TLD (tag library descriptor) is an XML document that defines a tag library. The servlet container uses the TLD for a tag library to interpret custom actions on certain JSP pages. The JSP pages reference that tag library through a taglib directive. At the highest level, the TLD defines attributes of the tag library as a whole. These properties might include its version number and the version number of its intended servlet container. At a lower level, the TLD defines each tag in the library.

The IDE enables you to create and edit TLDs without writing XML code. You create a TLD from the tag library template provided by the IDE. After you have created a TLD, you can edit it from the Explorer through menu commands. You can also edit the TLD through its customizer windows and its elements.

Inserting Custom Actions From a Tag Library Into a JSP Page

Custom actions are also commonly referred to as custom tags. However, the term custom action generally refers to the code construct used in a JSP page. The term custom tag generally refers to the code that implements the functions of a custom action.

Use the features of a tag library by coding custom actions in your JSP pages. For custom actions to use the tag library, the JSP page must declare the tag library with a taglib directive.

For example:

<%@taglib prefix="mt" uri="/WEB-INF/lib/myTagLib.jar" %>

The uri attribute of a taglib directive references either the TLD or a packaged tag library JAR file. The JAR file contains both the TLD and the tag handler beans. You must place the taglib directive before any custom actions that use the tag library. As an alternative, the uri attribute can be specified in the web module's deployment descriptor.

The previous example's uri attribute specifies a path relative to the root of the web module. The leading slash denotes the web module root.

Code completion works for the standard tag library in the <%@taglib> directive. For instance, in the example above, you need only type in the " (quotes) after the uri attribute name.

When you get to uri, then type =" and press Ctrl-Spacebar. The list of URIs available in this web context is displayed.

New with the JSP 1.2 specification, some tag libraries can contain more than one TLD in the JAR file. To obtain and use these tag libraries, place the JAR file in the WEB-INF/lib directory, and use the URI for the desired TLD in the uri attribute of the taglib directive.

To find the URIs for the TLD files in a JAR file, place the JAR in the WEB-INF/lib directory. The JAR file is then mounted in the Filesystems tab below the web module. Open the mounted JAR file in the Explorer, and select the META-INF directory, which contains the TLD files. If you double-click any of the TLD files, a customizer appears with the URI.

For example, the taglib directive for the core TLD from JSTL's standard.jar file would be:

<%@taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

You must place the taglib directive somewhere in the JSP page before the first custom action that uses the tag library.

During tag library development, your taglib directive should reference a TLD file rather than a tag library JAR file. The IDE inserts the class names of your tag handlers into the TLD. The tag handlers must also be in your web module's classpath. Place the tag handlers in the WEB-INF/classes directory.

Use the prefix attribute of the taglib directive to specify an identifier. Then use this identifier to refer to the tag library from custom actions coded in the JSP page. In the example, the taglib directive and the custom action (defined in the specified tag library) must be in the same JSP page. The action uses the prefix mt to refer to the tag library. The string table is the name of the tag.

<mt:table results="productDS"/>

The mapping between the tag name (in this case, table) and the tag handler bean is specified in the TLD. Edit this mapping in the Tag Customizer window, accessible in the Explorer from the tag's contextual menu.

Developing Your Own Tag Libraries

Many useful tag libraries, in addition to the JSTL and the tag libraries included in the Struts framework, are available. For more information on the Struts framework, see Struts. In addition, you might visit the following website, which is devoted to custom tag libraries, as a source: http://jsptags.com/

In many cases, you might want to encapsulate your business logic in your own custom tags. This way JSP pages in your web module can obtain and use the business logic easily. The tag format is familiar to web designers. Hence, the creation of custom tag libraries facilitates the insertion of these features into their JSP pages.

This section describes the support provided by the IDE for the process of developing custom tag libraries, including:

  • Creation and specification of tag libraries
  • Creation and specification of tags
  • Creation and specification of tag attributes
  • Creation and specification of scripting variables
  • Generation of tag handlers

Creating a Tag Library and Tags

As previously described, a tag library consists of a set of tag handler classes that implement the tag library's feature set and a TLD that describes the tags in the library and maps each tag to a tag handler. When you create a new custom tag library, you are actually generating a new TLD file.

You can create a tag library in either a new or an existing web module or filesystem. Right-click the root directory of the web module or filesystem in which you want to create a tag library. From the contextual menu, choose New, then choose JSP & Servlet, then choose Tag Library. This operation creates a TLD file. Use the Tag Library Customizer to define the properties of your custom tag library.

In the Tag Library Customizer, specify a short name, a display name, a Tag Library version, and a URI for your tag library. Set the Tag Handler Generation Root to the WEB-INF/Classes directory in your web module. The tag handler classes you generate are placed in this directory. You can also set code generation options and provide descriptive information about the tag library's features. For more information about the properties in the Tag Library Customizer, see the "Customizing Tag Libraries" in the JSP/Servlet online help.

The contents of the Tag Library Customizer reflect the properties of the selected tag library. The Tag Library Customizer shows the properties of any selected tag library. Once the properties for your tag library are specified, you can add and customize tags.

For more information about creating and using custom tag libraries, see JavaServer Pages Specification, Version 1.2 available at http://java.sun.com/products/jsp

It is recommended that you add a tag library directly to the web module when you create it using the IDE. Make sure to create the Tag Library TLD within the web module's WEB-INF directory. Moreover, the tag handlers should be generated into a package within the Classes directory. When you are ready to deploy the web module, package the tag library. Then replace the tag handler package in the Classes directory with the JAR file. The JAR file is then placed in the lib directory. See Packaging and Deploying a Custom Tag Library for details on packaging.

Adding and Customizing Tags

A custom tag consists of a tag signature plus a tag handler, which is a body of Java code. The IDE generates skeleton code for tag handlers based on specifications you supply in the Tag Customizer dialog box. You then edit the tag handler code directly to insert the logic that implements the features of the tag.

You can create a tag in the Explorer. Right-click the node representing the TLD to which you want to add a tag. From the contextual menu, choose Add New Tag. In the Add New Tag dialog box, edit the tag. See the "Tag Customizer Fields" section in "Customizing Tags" in the JSP/Servlet online help for more information.

You can also edit an existing tag in the Explorer. Right-click the tag you want to customize. From the contextual menu, choose Customize. In the Tag Customizer dialog box, edit the tag. See the "Tag Customizer Fields" section in "Customizing Tags" in the JSP/Servlet online help for details.

The Tag Customizer dialog box has several tabs. The General tab contains values that are to be inserted in the TLD. The Code Generation tab provides options pertaining to the tag handler class generated for the tag.

You must choose the type of content that occurs in the body of the tag. See Specifying How the Body of a Custom Action Is Handled for descriptions of possible options.

Additionally, you must specify the name of the Java package for the generated tag handler classes. The default value is the tag library's Short Name.

If the generated tag handler is to contain code to find the parent, that is, the enclosing tag, click the Find Parent checkbox. The type is determined by the Of Type property. The parent's tag handler instance, if found, is placed in the variable specified by the As Variable property. If checked, Find Parent enables the Of Type and As Variable properties. The default value is unchecked. If Find Parent is checked, Of Type and As Variable must have values entered. See the "Tag Customizer Fields" section in "Customizing Tags" in the online help for more information.

Custom Actions With Bodies

Custom actions, in principle, can contain bodies. They have begin and end tags that enclose other actions, scripting elements, or plain text. For example, this sample custom action contains a body composed of plain text:

<mt:convertToTable>type distance / a 30,000 / g 5,500 / z 200</mt:convertToTable>

Specifying How the Body of a Custom Action Is Handled

Use the Body Content field in the Tag Customizer dialog box to specify how the body is handled. Display this window from the contextual menu of the custom action's tag handler. Then choose one of these values: JSP, empty, or tagdependent.

TABLE 4-1 explains the meaning of each choice.

TABLE 4-1 Meaning of Body Content Field in Tag Customizer Dialog Box

Body Content Field

Meaning

JSP

Body content is optional. The servlet container evaluates JSP elements and then passes the body to the tag handler. The tag handler processes the body and writes output to the out object according to your programming logic.

empty

Body content is not permitted.

tagdependent

Body content is optional. The servlet container does not evaluate JSP elements, but does pass the body to the tag handler. The tag handler processes the body and writes output to the out object according to your programming logic.


All tag handlers implement javax.servlet.jsp.tagext.Tag. Tag handlers that do not accept or process a body need only implement this interface. If there is a body, it is simply passed through to the output with the usual JSP processing. Tag handlers that process a body must also implement javax.servlet.jsp.tagext.BodyTag. This interface provides additional methods for handling this processing.

Adding and Customizing Tag Attributes

Tag attributes are parameters associated with tags. These parameters denote or provide values used during tag processing.

Use the Add New Tag Attribute dialog box to create tag attributes. The Tag Attribute Customizer dialog box enables you to edit existing tag attributes.

In the Add New Tag Attribute dialog, specify various properties for your new tag attribute. For details about the New Tag Attribute and the Tag Attribute customizers, see "Customizing Tag Attributes" in the online help.

Once the new tag attribute is added to the tag, the Tag Attribute Customizer is displayed. Then you can edit the attribute in the customizer.

Three fields are important to consider when creating an attribute:

  • Required Attribute checkbox. Select to indicate that the attribute must be given an argument whenever the tag is called. By default, the box is set to False.
  • Value evaluated at request time radio button. Select to specify that the value of the attribute can be dynamically calculated at request time. The button is set to True by default. This value is mutually exclusive with the Value evaluated at JSP translation time attribute, described below.
  • Value evaluated at JSP translation time radio button. Select to specify that the value of the attribute is static and determined at translation time. The button is set to False by default. This value is mutually exclusive with the Value evaluated request time attribute, described above.

For details on the kinds of attribute properties you can provide, see the "Tag Attribute Information" section in "Customizing Tag Attributes" in the online help.

Adding and Customizing Scripting Variables

A scripting variable is a value that a tag exports to a JSP page. This value can then be used in an expression or scriptlet.

Use the Add New Tag Scripting Variable dialog box to create new scripting variables. The Tag Scripting Variable Customizer enables you to edit the properties of scripting variables.

In the Add New Tag Scripting Variable dialog box, specify various properties for your new scripting variable. For more on the Add New Scripting Variable dialog and the Tag Scripting Variable Customizer, see "Customizing Scripting Variables" in the online help.

Once the new scripting variable is added, the Tag Scripting Variable Customizer appears. You can then edit the scripting variable in the customizer.

When creating a scripting variable, the Variable Type field is particularly important. You specify the variable type. Then you choose a standard type from the list in the combo box, or enter a Java class name.

For details on scripting variable properties, see the "Tag Scripting Variable Information" section of "Customizing Scripting Variables" in the online help.

Generating Tag Handlers

As you develop your tag library, you add code to the tag handler classes to implement the features your custom actions require. The IDE generates the tag handler classes for you. Generation includes any properties set in the Tag Customizer and the tag attributes and scripting variables you have added to the tag. You customize your tag library by adding tags as well as adding or modifying attributes and scripting variables. During this process, you can regenerate the tag handlers. This task accounts for the changes without losing your edits to the tag handler code. For additional information, see "Generating Tag Handlers" in the online help.

Generated Tag Handlers

Generated code appears in a package directory determined by the tag library's Tag Handler Generation Root. This attribute is a code generation property you set in the Tag Customizer. If the value is blank, the Generation Root defaults to the root of the filesystem containing the tag library.

As described previously, you generate tag handlers from a TLD. These generated tag handlers implement the interfaces appropriate for their corresponding custom actions. Additionally, all the tag handlers' required class members, including fields, methods, and properties, are generated. The exact list of class members depends on your TLD. Nevertheless, it always includes the methods required by the interfaces that your tag handler implements.

The specific class members generated depend on the attributes and scripting variables you have declared in your TLD. For example, if you declare an attribute called myAttribute, a property called myAttribute is generated in the tag handler.

Methods Generated

TABLE 4-2 lists the methods the IDE creates when you generate tag handlers. Methods used to get and set properties are not listed. The methods marked with an asterisk (*) denote that they are part of the Tag and BodyTag interfaces. These methods call the others, which are helper methods.

Not all methods in the Tag and BodyTag interfaces are generated. The tag handler class can be generated as extending the TagSupport or BodyTagSupport helper classes. These helper classes implement all the methods in their respective interfaces. Only the methods that need to be overridden are generated. If you need to override any other methods for the Tag or BodyTag interfaces, include them in the TagHandler file.

TABLE 4-2 Generated Methods in Tag Handlers

Interface

Method

Tag

*doEndTag
*doStartTag
otherDoEndTagOperations
otherDoStartTagOperations
shouldEvaluateRestOfPageAfterEndTag
theBodyShouldBeEvaluated
theBodyShouldBeEvaluatedAgain

BodyTag

All the methods generated for the Tag interface plus the following:

*doAfterBody
writeTagBodyContent


Regenerating Tag Handlers

To develop your tag library, add programming logic to the tag handler class files to provide features required by your custom actions. During development, you might need to add additional attributes or scripting variables to your TLD. If so, regenerate your tag handlers so the corresponding class members are created. In this case, some of the tag handler's methods are regenerated, and some are left untouched.

The IDE regenerates the methods doStartTag, doEndTag, and doAfterBody. The Source Editor does not permit you to edit these methods. This restriction is because your changes would be overwritten when you regenerated tag handlers.

Instead of editing the methods that get regenerated, place your custom code in methods that these regenerated methods call. For example, the doStartTag method calls the otherDoStartTagOperations and theBodyShouldBeEvaluated methods.

The doStartTag method also returns an int code value to indicate whether the body should be evaluated. In the IDE, use the otherDoStartTagOperations method for the processing that needs to be performed at the beginning of the tag. Use the theBodyShouldBeEvaluated method to return a boolean value that is translated into the correct code value. Code placed in these two methods is not affected by regeneration.

TABLE 4-3 indicates which methods are regenerated and which methods you can edit.

TABLE 4-3 Editable Methods in Tag Handlers

Do Not Edit These Methods

Put Your Custom Code in These Methods Instead

doEndTag

otherDoEndTagOperations
shouldEvaluateRestOfPageAfterEndTag

doStartTag

otherDoStartTagOperations
theBodyShouldBeEvaluated

doAfterBody

writeTagBodyContent
theBodyShouldBeEvaluatedAgain


Testing Tag Libraries

You can create tag libraries in their own IDE filesystem, or within an existing web module's filesystem. Sometimes your tag library isn't already in a web module. In this case, convert the filesystem containing the tag library into a web module, as follows:

1. From the contextual menu, right-click Tools. Then choose Convert Filesystem into Web Module.

2. Leave the .tld file and the generated and compiled Java tag handler classes in place.

3. Right-click the root of the filesystem, and select Convert Filesystem into Web Module from the Tools menu.

4. Add the Tag Libraries element in the deployment descriptor for /<yourTagLib>.tld.

5. Create a JSP page, and add references to your new tags.

6. Execute your JSP file.

After testing your tag library, you can include it in other web modules by packaging it as a JAR file. For more information, see "Packaging and Deploying a Custom Tag Libraries" in the JSP/Servlet online help.

To facilitate the use of this tag library in other web modules, you should add your new tag library JAR file to the Tag Library Repository in the IDE. For details, see "Adding a Custom Tag Library to the Repository" in the JSP/Servlet online help.


Working With Databases

Database interaction is a significant aspect of web application development. The information contained within a database is used to drive the dynamic nature of JSP files and servlets within a web module. Hence, access to this data can be crucial.

When you want to work with a database in your application, create beans to access the database. Then use tag handlers to access the beans.

The IDE provides several tools that enable you to view and modify databases that supply JDBC drivers. See Using Java Database Connectivity for more detailed information.

When using JDBC to gain access a database from within your web application:

1. Create data access beans with methods to initialize connections to the database, including the management of connection pools and caches

2. Gain access to specific information using queries

3. View and update the information in row sets

For an example of creating a data access bean, see: "Duke's Bakery, Part II, A JDBC Order Entry Prototype - Continued" by visiting the following website:

http://developer.java.sun.com/developer/technicalArticles/
Database/dukesbakery2/

These data access beans can then be used directly by servlet or filter classes. You can also refer to them from within a JSP file using the jsp:useBean tag. For more information, see Using Additional Classes or Beans.

The PointBase database and the internal Tomcat 4.0.1 web server are configured by default to work together in the IDE. When using other databases or deploying to other web servers, you have two options. Add the database driver files to one of two locations:

  • The web module's WEB-INF/lib directory
  • The web server's common lib directory. For the internal Tomcat 4.0.1 web server, this directory is <ide-install-dir>/tomcat401/common/lib

Use the IDE's Database Explorer to confirm your connection to a database and your access to an appropriate driver for it. The Pointbase database is installed by default. For information on starting the PointBase database, see "Enabling a Database Connection With the IDE" in the online help. Even though the IDE's DB Explorer can be configured to use a particular database, you are still required to place the appropriate driver in the web module or the web server.

To utilize tags that simplify query and presentation tasks, you can add custom tag libraries to the web module. For details, see Developing Your Own Tag Libraries.

It is recommended that you create custom tags to:

  • Display data to the user
  • Query data
  • Update data in the database

Adding these tags to your web module simplifies the addition of query and presentation tasks within the JSP page. It also provides the clean separation of business logic code from its presentation to the end user. See the J2EE Tutorial for an example of an IDE-developed web application that accesses a database.

The tag handler classes for these tags can directly gain access to the methods in the data access bean. In order to use a tag library, you import it into the JSP file. See Using Tag Libraries for details.

For information on the Database access tags within the JSTL, visit this website:

http://jakarta.apache.org/taglibs/doc/standard-doc/Overview.html