C H A P T E R  2

Scenario: A Web Module

FIGURE 2-1 shows a web module. Of the many possible combinations of web components, this module contains two servlets and a static HTML page. It engages in interactions that are typical of web modules in J2EE applications. Web modules provide front ends for J2EE applications, so they must be able to interact with end users over HTTP connections (represented in the figure by the arrows labeled #1), and with services provided by EJB modules (the arrows labeled #3). There are also interactions between the components in the module (represented by the arrows labeled #2).

 FIGURE 2-1 Web Module for a J2EE Application

Diagram of the web module covered in this chapter.[ D ]


The Interactions in This Module

This scenario looks at a web module that participates in the three types of interaction shown in FIGURE 2-1. The module is part of a J2EE application that supports a retail web site. Within the web site application, the web module is used to provide front-end functionality for a J2EE application. This is a typical role for a web module in a J2EE application.

From the shopper's point of view the application is a series of web pages. Shoppers use a web browser to open HTTP connections to a URL that maps to the application's context root and provide input with text fields, buttons, and other controls that appear on the web pages. From the developer's point of view, the application is a set of components that receive and process requests.

This scenario uses a simple web module that processes two different requests to show how web components can provide the necessary interaction between users, web module, and EJB module. More specifically, displaying the online shopping catalog uses these interactions:

1. An online shopper opens a connection to the application by starting a web browser and opening the application's root URL. This opens the application's welcome page. A real-world shopping site's welcome page would display a number of options, including requests for displaying items by category, requests for keyword search, requests for information about live customer service, and so on. This simple example shows only one link, to a display of the entire catalog.

2. The shopper clicks the link to the catalog display. This request is processed by the servlet named in the request, AllItemsServlet. AllItemsServlet processes the request by calling a business method of the EJB module, getAllItems, which returns the data.

3. AllItemsServlet formats the data returned by getAllItems and adds them to an HTML output stream. The end user's web browser formats the HTML output into a catalog display. The output includes links to detailed information about each item.

4. The end user browses the displayed catalog, and clicks on one of the links to detailed information. This request is processed by another servlet, DetailServlet. DetailServlet processes the request by calling another business method of the EJB module, getOneItemDetail, for the item detail information.

5. DetailServlet adds the data returned by the EJB module to an HTML output stream, which is displayed to the end user as another web page.

There are two possible requests in this scenario, and each of them is processed by a separate web component. Servlets were used for this example, so there is an AllItemsServlet and an ItemDetailServlet.

The HTML outputs written by these servlets are simple, and include only text. These examples show you web components can process HTTP requests by using remote methods calls to obtain data from an EJB module and then writing that data into an HTML output stream. The same type of operation can be used by an experienced web designer or web programmer to write much more complex output.

The type of interaction the web module has with the EJB module, Java RMI, is determined by the design of the EJB module. For more on this, see The Interactions in This Module.

For instructions on creating web components, writing enterprise business logic in web components, and similar tasks, see Building Web Components.


Programming This Module

TABLE 2-1 summarizes the programming required to create the EJB module illustrated in FIGURE 2-1.

TABLE 2-1 Programming Required for This Scenario

Application Element

Programming Required

Application server

None.

Web module

Create the web module.

Create the welcome page, index.html. This page includes an HTML link that executes the AllItemsServlet.

Create two servlets, AllItemsServlet and ItemDetailServlet.

Code the processRequest methods that process HTTP requests: and generate HTTP responses. These processRequest methods:

  1. Perform JNDI lookup in order to invoke EJB module business methods.
  2. Write the data they obtain from the module into the servlet's response.

Notice that the HTML page output by AllItemsServlet contains an HTML link to ItemDetailServlet.

Set up servlet names for each servlet.

J2EE application

To see how you add a web module to a J2EE application, see Chapter 4.


The sections that follow show you how to perform many of these programming tasks. Method signatures are used to show the inputs and outputs of each interaction. The procedures show how to connect these inputs and outputs to other components and other modules. Instructions for creating a web module, or adding the web components to the module are not included. If you need to learn about these tasks, see the online help or Building Web Components.

Creating the Welcome Page

The design for the catalog display web site is for users to begin their interaction with the site at a welcome page. The welcome page, a typical web site feature, provides an entry point for users that identifies the site, and presents the different options available to them. Once they've seen the welcome page, users can click their way to the features they want to use.

The user's first request is to enter the application's root URL. If a welcome page has been provided, the server will display it.

Creating the HTML Page

In the Explorer window, the HTML file for you welcome page should be at the same level as the web module's WEB_INF node. To create an HTML file at the right level:

1. Right-click the node for the filesystem that contains the green WEB-INF node, and choose New right arrow JSP & Servlet right arrow HTML File. Supply the name index and click Finish.

This creates an HTML file node in the Explorer and opens the new file in the source editor.

2. Type in the HTML code for your welcome page.

CODE EXAMPLE 2-1 shows the HTML code for the simple welcome page used in this scenario.

CODE EXAMPLE 2-1 Catalog Display Module Welcome Page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
<html>
  <head>
    <title>Online Catalog</title>
  </head>
  <body>
<h2>
Inventory List Application
</h2>
  
<p>
<a href="allItems">Display the Catalog
</a>
 
</body>
</html>

This welcome page presents only one option to users, which is to display the entire catalog. This option is presented as a text link named "Display the Catalog." This link uses a URL to specify one of the servlets in the module, AllItemsServlet. When a user clicks on this link, the browser sends another request to the web module. This request will be processed by executing AllItemsServlet's doGet method, and the next page the user sees is the page output by AllItemsServlet. (To see the page output by AllItemsServlet, see CODE EXAMPLE 2-2.)

The welcome page for a real-world web site includes many links, to different functions, but each follows the principle demonstrated in this example, that a page displayed to the user contains links or actions that generate requests. Each request is processed by some component in the web module, and that component responds by writing out the next page that the user sees.

In this case, the link specifies a servlet name. The default action is to execute the servlet's doGet method. When specified, a link can execute the servlet's other methods, doPost, and so on. For more information on servlet methods, see Building Web Components.

Specifying Your Page as the Welcome Page

When you create a web module in the IDE, the Welcome Files property lists some default names for the welcome files. FIGURE 2-2 shows the Welcome Files Property Editor with the default welcome file names. When a user accesses the root URL for the application, the application server searches in the module directory for the files named in this property. The first one found is displayed as the welcome page.

The easiest way to create welcome file for the module is to create a file with one of these default names and add it to the module. In this scenario, for example, you created a file named index.html.

 FIGURE 2-2 Welcome Files Property Editor

Screenshot of Welcome Files property editor, showing the default welcome file names of index.jsp, index.html, and index.htm.

If you want to use a file with a different name for the module's welcome page, open the editor for the Welcome Files property and add the name of the file you want to use. You can use the other buttons to reorder the files or to remove the default names from the list or to move them below the name you add.

Programming the Servlet Methods

There are two parts to this, coding the method body and setting up a reference declaration for the EJB reference used in the method body. The method body code is covered first.

The servlets in this example were create with the IDE's servlet template. Servlets created with this template are HttpServlets, and they contain methods named processRequest. The doGet and doPost methods both call processRequest, so the code that actually processes a request is added to the processRequest method.

The Method Body

CODE EXAMPLE 2-2 is the implementation of the AllItemsServlet's processRequest method. This method is executed when a user clicks on the Display the Catalog link that appears on the welcome page. (The request generated by the browser names the AllItemsServlet, by URL, but it does not specify a method, so the application server performs the default action and executes the servlet's doGet method, which calls processRequest.)

This method implementation shows you how the servlet obtains the catalog data and displays it to the user. There are three steps:

1. The servlet uses JNDI lookup to obtain a a remote reference to a session enterprise bean in another module of the application.

2. The servlet calls getAllItems, a business method of the session bean. (For more about the CatalogData module, see Chapter 3.)

3. The servlet writes the data returned by the remote method call into the HTML output stream, which is returned to the user's browser window.

CODE EXAMPLE 2-2 AllItemsServlet's processRequest Method
protected void processRequest(HttpServletRequest request, 
 HttpServletResponse response)
throws ServletException, java.io.IOException {
        response.setContentType("text/html");
        java.io.PrintWriter out = response.getWriter();
        /* output your page here */
        out.println("<html>");
        out.println("<head>");
        out.println("<title>AllItemsServlet</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h2>The Inventory List</h2>");
        
        out.println("<table>");
        out.println("<tr>");
        out.println("<td>Item");
        out.println("<td>Item SKU");
        out.println("<td>Detail");
              
        CatalogBeans.CatalogManagerBeanHome catHome;
        CatalogBeans.CatalogManagerBean catRemote;
        
        try {
            InitialContext ic = new InitialContext();
            Object objref  = ic.lookup("java:comp/env/ejb/CatalogManagerBean");
            catHome = (CatalogBeans.CatalogManagerBeanHome) objref;
            catRemote = catHome.create();
            
            java.util.Vector allItems = catRemote.getAllItems();
            
            Iterator i = allItems.iterator();
            while (i.hasNext()) {
                
                CatalogBeans.iDetail itemDetail = (CatalogBeans.iDetail)i.next();
                out.println("<tr>" +
                "<td>" +
                itemDetail.getItemname() +
                
                "<td>" +
                itemDetail.getItemsku() +
                
                "<td>" + 
                "<a href=\"" + response.encodeURL("DetailServlet?sku=" + itemDetail.getItemsku()) + 
                "\"> " +
                "Get Item Detail" +
                "</a>");
            }
        }
        catch (javax.naming.NamingException nE) {
            System.out.println("Naming Exception on Lookup" + nE.toString());
        }
        catch (javax.ejb.CreateException cE) {
            System.out.println("CreateException" + cE.toString());
        }
        catch (java.rmi.RemoteException rE) {
            System.out.println("RemoteException" + rE.toString());
        }
        catch (Exception e) {
            System.out.println(e.toString());
        }
        
        out.println("</table>");
                
        out.println("</body>");
        out.println("</html>");
        out.close();
    }

The lookup statement specifies "CatalogManagerBean," but this string is actually the name of the reference, not the referenced enterprise bean. The enterprise bean's name is often used as the reference name, to make it easier to remember which bean is meant. The actual enterprise bean is specified in the next step.

The Reference Declaration for the EJB Reference

A web component like AllItemsServlet, which is going to call methods of an enterprise bean in an EJB module, does so by means of EJB references. There are two parts to an EJB reference:

  • JNDI lookup code, which uses the JNDI naming facility to obtain a remote reference to a named enterprise bean.
  • A declaration of the reference. This is used by the runtime environment to identify that specific bean referred to by the lookup code.

The lookup code is in the processRequest method (see CODE EXAMPLE 2-2). To use the lookup code, you need to set up a reference declaration. The reference declaration maps the reference name used in the lookup statement to an actual enterprise bean that will be deployed with the web module. To set up an EJB reference declaration for a web module:

1. Right click the web.xml node, and then choose the following sequence of commands from the contextual menu: Properties right arrow References tab right arrow EJB References right arrow ellipsis (...) button.

This opens the EJB references property editor.

2. Click the Add button.

This opens a dialog that you use to set up the reference declaration.

3. To add a reference declaration you must supply the reference name used in the lookup statement and the home and remote interfaces used in the method calls.

FIGURE 2-3 shows the add dialog with these values in the fields. For the reference to work at runtime, for the JNDI lookup to return a remote reference to an enterprise bean, the reference must be linked to a specific enterprise bean, in the same application. This must be done before you deploy and execute the application, but it need not be done now.

At this point in development, you can leave the reference unlinked, and link it later, after you assemble the web module into a J2EE application. In some circumstances, you might choose to resolve the reference at this stage of development.

a. If the enterprise bean is not in your development environment, you cannot link the reference. Supply the names of the interfaces and click OK. You must have copies of the interfaces in you development environment, in order to compile the JNDI lookup code.

FIGURE 2-3 shows the property editor setting up an unlinked reference. The Home Interface and Remote Interface are specified but the Referenced EJB Name field is empty. The reference will be linked later on the application property sheet.

 FIGURE 2-3 EJB Reference Property Editor With Unlinked Reference

Screenshot of EJB Reference Property editor with values in Reference Name, Type, Home Interface, and Remote Interface fields.[ D ]

b. If the enterprise bean is available in your development environment, you can link the reference now. Click the browse button next to the Referenced EJB Name field. Use the dialog that appears to select the enterprise bean. Click OK. FIGURE 2-3 shows the reference named ejb/CatalogManagerBean linked to CatalogManagerBean.

Even when the enterprise bean is available, you might choose not to link the reference now. There are a number of reasons not to. For example, if there is any chance that your web component will be used in more than one application, you do not want to link the reference on the module's property sheet. Any subsequent developer who uses the module could relink the link to some other enterprise bean that implemented the same interfaces.

 FIGURE 2-4 EJB Reference Property Editor With Linked Reference

Screenshot of EJB Reference Property editor with additional value in Referenced EJB Name field.[ D ]

In this scenario, the reference is left unlinked, as shown in FIGURE 2-3, and it is linked after the J2EE application is created, on the application node's property sheet. See Linking the EJB Reference.

Mapping URLs to the Servlets

The link you set up on the welcome page specified the business logic that executes (when a shopper clicks the link) with the following URL:

<a href="allItems">

For this link to work properly, the URL you supply must map to the servlet you want to execute. To understand how this works, you need to know how URLs map to web resources.

Understanding Servlet Mappings

In a deployed application, the URLs for web resources in the web module are the result of appending names to a URL path. For the J2EE Reference Implementation, the URL path has this general form:

http://hostnmame:port/web_context/URL_pattern

The elements in this path are determined by the following:

  • The hostname is the name of the machine the application server is running on, and the port is the port specified for that server instance's HTTP requests. The port number is usually assigned when the application server is installed. For the J2EE RI that is installed with Sun ONE Studio 4, the HTTP port number is 8000.
  • The web context is a string that you specify as a property of the module, after you add the module to a J2EE application (on the included web module's property sheet). It qualifies all of the web resources in the module.
  • The URL pattern is a string that identifies a specific servlet or JSP page. You assign it on the web module property sheet.

In other words, the URL patterns you assign in your web module are relative to the web context that you will assign later, when you add the module to a J2EE application. The HTML in this scenario uses links that are relative to the web context, so that whatever web context you supply when you assemble the application, the links will work properly when you execute the application. For information on setting the web context, see Setting the Web Context for the Web Module.

Editing Servlet Mappings

When you create a servlet, the default behavior of the Servlet Wizard is to use the class name you supply on the first page of the Servlet Wizard for the servlet name, and to map the servlet name to a URL pattern that includes the servlet name. FIGURE 2-5 shows the Servlet Mappings property editor for AllItemsServlet with these default settings.

 FIGURE 2-5 Servlet Mappings Property Editor

Screenshot of Servlet Mappings Property Editor with default mappings for AllItemsServlet and DetailServlet[ D ]

If you deploy the web module with this servlet mapping, AllItemsServlet is mapped to the following URL:

http://hostname:port/web_context/servlet/AllItemsServlet

If you want to map another URL to the servlet, you use the servlet mappings property editor to edit the mapping. This scenario changes the URL pattern to a more useful value

To edit the servlet mapping:

1. Open the Servlet Mappings Property Editor. Right-click the web module's web.xml node and choose the following sequence of commands on the contextual menu: Properties right arrow Servlet Mappings right arrow ellipsis (...) button.

The Servlet Mappings Property Editor will list all servlets in the module and any mappings that have been set up for them.

2. Select the current mapping and click the Edit button.

This opens a dialog that lets you edit the servlet mapping. Type /allItems in the URL Pattern field. Click OK. FIGURE 2-6 shows the servlet mappings edit dialog with new mappings for AllItemsServlet and Detail Servlet.

 FIGURE 2-6 Servlet Mappings Property Editor

Screenshot of Servlet Mappings Property Editor with edited mappings for AllItemsServlet and DetailServlet.[ D ]

After you edit the servlet mapping, AllItemsServlet can be executed with the following URL:

http://hostnmame:port/web_context/allItems

This is the URL you used for the link that appears on the welcome page (see CODE EXAMPLE 2-1). Clicking on that link now executes AllItemsServlet.

Other Assembly Tasks

This section covers some assembly tasks that were not used in the scenario. You might find them useful in your web modules.

Setting up Error Pages

If you want to specify error pages for the module, you need to identify them in the module's deployment descriptor. You do this in the Error Pages Property Editor. (To open this property editor, right-click on the web.xml icon, and then choose the following sequence from the contextual menu: Properties right arrow Deployment Tab right arrow Error Pages right arrow ellipsis (...) button.

You can identify errors either by an HTTP error code or a Java exception class. Notice that the editor has two Add buttons, on for each category of error. For either type, you just specify the error and map it to a page. FIGURE 2-7 shows the property editor after an error page has been assigned to HTTP error code 404.

 FIGURE 2-7 Error Pages Property Editor

Screenshot of Error Pages property editor showing Help Error Code 404 mapped to ErrorPage.jsp.

Setting up JSP Pages

If the web module you are assembling contains JSP page components, you have a number of ways to execute those components. If you create a new JSP page named myJsp, you can execute it in any of the following ways.

Executing JSP Pages With HTML Links

If you want to execute a JSP page from an HTML link, set the link up like the following example.

<a href="myJsp.jsp">Execute myJsp>

Executing JSP Pages Programmatically

If you create a JSP page with the IDE, no deployment descriptor entry is created for it. This is not a problem when your business logic accesses the JSP page programmatically. For example, the following code is from a servlet that executes myJsp. Notice that it specifies the actual filename for the JSP page (myJsp.jsp):

...
response.setContentType("text/html"); 
        RequestDispatcher dispatcher; 
        dispatcher = getServletContext().getRequestDispatcher ("/myJsp.jsp"); 
        dispatcher.include(request, response); 
...

Using URL to JSP Mappings

The preceding examples identify the JSP page to execute by it's actual name, myJsp.jsp. You can also map a URL pattern to a JSP page and then execute the page by referring to its URL pattern.

To set up a URL mapping for a JSP page:

1. Set up a servlet name for the JSP page.

You do this with the JSP Files Property Editor.

a. Right-click the web.xml file, and then choose the following sequence of commands form the contextual menu: Properties right arrow Deployment Pane right arrow JSP Files right arrow ellipsis (...) button.

This opens the property editor.

b. Click the Add button. This opens a dialog on which you can select a JSP page file and assign a servlet name to it.

FIGURE 2-8 shows the JSP Files Property Editor after the servlet name itemDetailPage has been mapped to myJsp.jsp.

 FIGURE 2-8 JSP Files Property Editor

Screenshot of JSP Files property editor.[ D ]

2. Map a URL pattern to the servlet name.

a. Open the Servlet Mappings Property Editor. Click the Servlet Mappings property and click the ellipsis (...) button.

b. On the Servlet Mappings Property Editor, click the Add button. This opens a dialog that lets you set up a new servlet mapping.

Type in the servlet name you assigned to the JSP page. Then type in the URL pattern you want to map to the JSP page. FIGURE 2-9 shows the Servlet Mappings Property Editor with the URL pattern ItemDetail mapped to the servlet name ItemDetailPage.

 FIGURE 2-9 Servlet Mappings Property Editor

Screenshot of Servlet Mappings property editor.[ D ]

After this mapping, the JSP page defined by the JSP file myJSP.jsp can now be executed with the following URL:

http://hostnmame:port/web_context/ItemDetail

Setting up Environment Entry References

There are two parts to an environment entry:

  • A JNDI lookup. The web component that is to use the environment entry uses the JNDI naming facility to lookup the entry's value.
  • An entry for the environment entry and its value in the web module's deployment descriptor. This entry declares the reference to the J2EE runtime environment.
JNDI Lookup for Environment Entry References

A web component that uses the environment entry value needs code like the following example:

try {
	// Obtain Initial Context--Opens Communication With JNDI Naming:
	Context ic = new InitialContext();
	// Request Lookup of Environment Entry Named "Cache Size":
	Integer cacheSize = (Integer)
	 ic.lookup("java:comp/env/NumberOfRecordsCached");
} 
catch(Exception e) {
	System.out.println(e.toString()); 
	e.printStackTrace();
	return; 
} 

The comments explain what each line does.

Reference Declaration for Environment Entries

Like the other kinds of J2EE references, you set this one up in a property editor. In this case it is the Environment Entries Property Editor. (To open this property editor, right-click on the web.xml node, and then choose the following sequence of commands from the contextual menu: Properties right arrow References tab right arrow Environment Entries right arrow ellipsis (...) button.

Click the Add button to open a dialog that lets you add a new reference. To add a reference you must supply a reference name that matches the JNDI name in the web component code, a data type and an initial value. Use the description to help application assemblers and deployers supply the correct value for their environments. FIGURE 2-10 shows the Environment Entries Property Editor with these fields filled in.

 FIGURE 2-10 Environment Entries Property Editor

Screenshot of Add Environment Entry dialog. Field values are, Name, NumberOfRecordsCached, and Value, 100.