Novell is now a part of Micro Focus

How to Build J2EE Applications Using Novell Technologies: Part 2

Articles and Tips: article

J. Jeffrey Hanson
Chief Architect
Zareus Inc.
Jhanson583@aol.com

01 Jun 2002


This AppNote is the second in a series that outlines a platform and methodology for developing applications on NetWare with the Java 2 Platform Enterprise Edition (J2EE) using a service-oriented architecture. This AppNote shows how to handle HTTP requests, dispatch the requests and respond with device-independent presentation code.


Topics

Java application development, J2EE, servlets

Products

Java 2 Enterprise Edition

Audience

developers

Level

intermediate

Prerequisite Skills

familiarity with Java programming

Operating System

n/a

Tools

none

Sample Code

yes

Introduction

This is the second in a series of AppNotes that outlines a platform and methodology for Java 2 Platform Enterprise Edition (J2EE) application development on NetWare using a service-oriented architecture.

The first AppNote introduced the technologies for the series, including Java Messaging Service (JMS), servlets, Java Server Pages (JSP), Enterprise JavaBeans (EJB), and so on. It also introduced some J2EE enhancement technologies, including Novell eDirectory/ LDAP, Java Management Extensions (JMX), Jini, and JavaSpaces.

We will be using these technologies to build a complete, service-oriented platform for developing, deploying, and managing applications and services, using proven design patterns. These applications and services will be deployed and used within multi-tier client/server environments, peer-to-peer environments, fat-client environments, and X-Internet environments. We defined the platform as a comprehensive array of components and modules distributed across four tiers: the client tier, the Web tier, the business tier, and the enterprise information system (EIS) tier.

In this AppNote we are going to begin our journey into the J2EE development world by developing a servlet on the Web tier that will respond to HTTP requests sent from a browser on the client tier. This servlet will act as the point of control for all HTTP-based requests. This "controller" servlet will dispatch requests from clients to business-logic components and respond to clients with device-independent presentation code.

Development Tools for Non-Keynesian Bohemians

The first order of business is to choose a development environment. Since our target application will be browser-based, we don't need to worry about adhering to a specific client OS. Because our server components will be entirely Java-based, we need to choose a development environment that allows us to produce Java code. This opens up all kinds of possibilities, as far as a development environment is concerned.

Now, being an incurable free-market consumer, I like to think of myself as a true patriot in the battle for a stronger economy. I wield my credit cards with unbridled recklessness, feeding VISA and MasterCard enough interest to finance a third-world country. However, when it comes to choosing a product from my very own industry, I brazenly choose a free one: NetBeans . . . go figure!

NetBeans 3.3.1 is a full-featured, open source, integrated development environment (IDE) that can be used to develop code in Java, HTML, and other languages. You don't have to brandish any credit cards in order to acquire this open-source tool. Simply point your browser to the NetBeans Web site (http://www.netbeans.org), download the tool, and install it as directed.

You can install the NetBeans development tool on any desktop OS that supports Java. However, being the true bohemian (and cheapskate) that I am, I choose to defy the bourgeois establishment and install it on my Penguin-oriented, open source desktop. Your choice of desktops is up to you - if you choose to support our friends from Redmond, I respect your right to do so.

This Means WAR

A Web application can be very loosely defined as "a bunch of stuff grouped together and given a name and address." A slightly more formal definition might explain that this bunch of stuff can be made up of HTML files, servlets, images, JSP files, property files, text files, Grandma's pumpkin pie recipe, and little Johnny's report card. You can take all this stuff, group it together, give it a name like "GrannysGoods", give it an address like /webapps/GrannysGoods, and call it a Web application.

The Servlet 2.2 specification (see http://java.sun.com/products/servlet/download.html) introduced a new entity called the "Web Application Archive," or WAR file. This evil-sounding creature is actually a deployable version of a Web application, containing the directory structure for the application and the files they contain. These items are combined into a zip-formatted file with a .war extension.

To deploy a WAR file to Tomcat 3.3 on NetWare, you can take one of two paths:

  • Manually expand the archive to a directory and have that directory served as a Web application context (an instance of a Web application's resources being served with a unique context path).

  • Have Tomcat's AutoDeploy module do the expansion automatically by placing the WAR file in Tomcat's webapps directory. This will cause Tomcat to expand the WAR file whenever Tomcat is restarted.

To deploy a WAR file while Tomcat 3.3 is running, you will need to choose the first path and manually expand the WAR file. Then use the Admin Web application to add the context.

Putting Things in Context

In Tomcat 3.3, a "context" is a directory that contains the resources needed for the Web application. This directory must match the structure and requirements defined for a Web application as defined by the Servlet 2.2 specification. Once this directory is created, it may be acted upon by Tomcat as a context using one or both of the following mechanisms:

  • Use a ContextXmlReader to read a specified context configuration file, if it exists, and all files with an associated pattern. For example, the associated pattern "apps-*.xml" will configure the ContextXmlReader to pick up the apps-admin.xml, apps-example.xml, and apps-127.0.0.1 files. To add your own context definitions, you can create files with names like apps.xml or apps-mycoolapps.xml.

  • Create a subdirectory of a directory named in an AutoWebApp module. This will create a context that will be served using the context's directory name as the context path. The default installation of Tomcat 3.3 has one such AutoWebApp module which serves subdirectories of Tomcat's webapps directory.

Now that you know what a context is, it's time to press boldly on into battle to face the first line of demarcation: the "Web Tier."

Dispatches from the Web Tier

As mentioned in the previous AppNote in this series, the Web tier performs request dispatching duties for multiple clients. Client requests are routed through the Web tier to the business tier. The business tier performs services and formulates responses for requests passed to it from the Web tier. The Web tier uses servlets and JSPs to deliver responses in the form of view scripts (HTML, HDML, XML, and so on) to the client tier. The Web tier coordinates the flow of an application. Domain specialists work within the Web tier to structure the flow of each application. Sounds simple, right? Well, let's take a closer look.

Pretend your client is a banking customer (Joe) who wants to access his account information online, from any device that can access the Internet. Under ordinary circumstances, Joe simply sits at a PC, opens a Web browser, and begins a conversation between the browser and a Web application. But what if Joe is on a ski lift in the Alps with nothing but a mobile phone? Even under these harsh, primitive conditions, he can leap back into the civilized world with the touch of a few buttons and begin a conversation between the phone and a Web application. As an incredulous shout of "How can this be?" escapes from your lips, you hear a faint echo from across the vast expanse of the mountain range that answers, "With MVC, all things are possible!"

MVC Prescribed

MVC is the ever-popular Model-View-Controller design pattern for building modular applications. The above scenario is a good fit for this pattern, as the responsibilities are neatly segregated among the various tiers. You see, it is the Web tier's responsibility to intercept all incoming HTTP requests, dispatch these requests to appropriate request handlers that will parse the requests, and pass the data on to services lurking on the business tier. Once the business objects have done the voodoo that they do and the responses have been passed back to the Web tier, the Web tier must format the responses for the target client device and pass the request back in a form the client device can understand.

As if this list of responsibilities wasn't enough to worry about, we want to add even more challenges to the list. We want to construct our Web tier in such a way as to encourage modular component development and reuse, while maintaining a painless process for upgrading components and modules in the future. Again, we are going to use the MVC design pattern to do this.

In MVC, various components and objects separate the front-end of an application into three individual areas of functionality:

  • The Controller handles the flow of input and output requests. In a typical desktop application, this consists of mouse clicks, key clicks, system events, and so on. In a Web application, the Controller handles HTTP input requests and output responses.

  • The Model is responsible for maintaining the state of any data that is transferred between modules and components. The Controller uses the Model objects to transfer data to the business objects and to transfer response data to the View objects.

  • The View objects format pages of text, images, and so on using the data retrieved from the Model objects. The pages are then passed back to the client to be viewed on the client's device.

The following sections explain a little bit about the components and modules that we will be using to implement our MVC pattern, and then discuss the source code that we'll create.

Controlling the Front Lines

The first point of entry to our Web application happens as an HTTP request is received. Since Java servlets are designed for this very purpose, it makes sense to exploit this opportunity and construct a servlet to handle HTTP requests. The servlet will be constructed based on a widely-used design pattern, the Front Controller.

The Front Controller pattern solves several problems by channeling all client requests through a single object, the Front Controller servlet. This servlet then processes all requests, loads and responds with the next view to be displayed, and centralizes all security needs for each Web application.

Once the Front Controller has received an HTTP request, determined where it is to be dispatched, and extracted any parameter data from the request, the Front Controller gets a reference to a Model object, places any request data in the Model object, and then passes the Model object to a Task object to use while making a call into the business tier. The Task object takes the Model object passed back from the business tier, formats the data found in the Model object according to a markup file such as HTML, XSLT, JSP, and so on, and sends the response back to the client.

The following code sample demonstrates this interaction:

public class FrontController extends HttpServlet
{
   TaskMaster taskMaster = null;
   
   public void init()
      throws ServletException
   {
      taskMaster = new TaskMaster();
   }
   
   protected void doPost(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, java.io.IOException
   {
   process(req, res);
   }
   
   protected void doGet(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, java.io.IOException
   {
      process(req, res);
   }
   
   private void process(HttpServletRequest req, HttpServletResponse res)
   {
      taskMaster.process(req, res);
   }
}

Notice that the process method hands the request and response objects to the taskMaster instance in order for it to handle the view selection and response dispatching.

Taken to Task

This introduces a new soldier in our battle for the front: the TaskMaster. It is the TaskMaster's duty to dispatch requests as tasks to the appropriate business objects residing on the business tier. The TaskMaster then uses the data contained in the Model objects passed back from the business objects and script files created by Web page design experts to create the view pages that will be returned to the client.

The following code sample demonstrates this process:

public class HTTPTaskMaster
   implements TaskMaster
{
   private HashMap tasks = new HashMap();
   private ServletContext servletContext = null;
   
   public void init(ServletContext context)
      throws Throwable
   {
      
      this.servletContext = context;
      getTasksFromFile(tasks);
   }
      
   
   public boolean process(HttpServletRequest req, HttpServletResponse res)
   {
      String pathInfo = req.getPathInfo();
      String viewURL = execute(req, res, pathInfo);
      viewMaster.execute(req, res, viewURL);
      
      return false;
   }
   
   public String execute(HttpServletRequest req,
                        HttpServletResponse res,
                        String taskID)
   {
      Task task = tasks.get(taskID);
      return task.execute(req, res);
   }
}

Now, the final step is to take the data returned from the business object, format it, and pass it back to the client. For this we will call on the ViewMaster.

The View from the Front

The ViewMaster manages all views for a particular application. View properties are constructed and stored in XML files that can be edited by domain experts that understand the flow of control that the application must follow. With this model in place, the flow of an application can be controlled without modifying Java code.

The following code sample demonstrates the important functionality of the ViewMaster:

public class HTTPViewMaster
   implements ViewMaster
{
   HashMap  views = new HashMap();
      
   public void init(ServletContext context)
      throws Throwable
   {
      this.servletContext = context;
      loadViewsFromFile(views);
   }
   
   public void execute(HttpServletRequest req,
                     HttpServletResponse res,
                     String viewID)
   {
      req.setAttribute("CurrentView", viewID);
      
   View view = views.get(viewID);
   if (view != null)
   {
      setViewProperties(req, view);
      RequestDispatcher dispatcher =
                  servletContext.getRequestDispatcher(view.getURI());
      dispatcher.forward(req, res);
      }
   }
}

Battle Plans

Now that you have an outline of the components needed for the Web tier, let's see how to create them in our chosen programming environment. The steps explained here are for the NetBeans programming environment; you may need to adapt them to fit your chosen environment.

Creating the Project

To create the project in NetBeans, follow these steps:

  1. Select Project | Project Manager | New.

  2. Name your project "MyEStore".

  3. Click the OK button.

Adding the Web Module

To add the Web module, follow these steps:

  1. Select the "Project MyEStore" tab.

  2. Right-click on the Project MyEStore node and select the Add New menu item.

  3. Expand the JSP & Servlet tab and select the Web Module node.

  4. Click Next.

  5. Browse to the directory in which you want to store your application.

  6. Click Finish.

Creating the HTML File

To create the HTML file, follow these steps:

  1. Expand the new Web module node.

  2. Expand the Document Base node.

  3. Right-click on the Document Base node and select New -> JSP & Servlet -> HTML File.

  4. In the Object Name dialog, name the file index.

  5. Click Finish.

  6. Type some text in the body section of the HTML file and save the file.

Creating and Compiling the Front Controller Servlet

To create and compile the Front Controller servlet, follow these steps:

  1. Right-click on the WEB-INF | Classes node and select New | JSP & Servlet | Servlet.

  2. In the Object Name dialog, name the servlet ControllerServlet.

  3. Click Finish.

  4. The Java code for the servlet will be displayed. In the processRequest method, uncomment the lines containing out.println and add one new line as follows:

    out.println("Greetings from MyEStore ControllerServlet");
    
  5. Right-click on the WEB-INF | Classes | ControllerServlet node and select Compile.

Adding the Servlet to the Web Application File

To add the servlet to the Web application file, follow these steps:

  1. Right-click on the WEB-INF | web node and select Edit.

  2. The web.xml file will appear in the editor window. Insert the following lines directly after the <web-app> line:

    <servlet>
     <servlet-name>
      Controller
     </servlet-name>
     <servlet-class>
      ControllerServlet
     </servlet-class>
    </servlet>
    

Deploying the Application

To deploy the application, follow these steps:

  1. Right-click on the Web module node and select Tools | Export WAR File.

  2. Choose a directory in which to export the WAR file, name the WAR file MyEStore and select OK.

  3. Copy the WAR file to sys:/tomcat/33/webapps.

  4. Copy the directory containing the output files for the MyEStore project to sys:/tomcat/33/webapps.

Creating the Context

To create the context for the application, follow these steps:

  1. Direct your browser to http://yourserver/admin.

  2. Select the Context Admin link.

  3. In the Path: box, type /MyEStore.

  4. In the Document Base: box, type webapps\MyEStore.

  5. Click the Add Context button.

Testing the Application

To test the application you have created, follow these steps:

  1. Direct your browser to http://yourserver/MyEStore.

  2. Direct your browser to http://yourserver/MyEStore/servlet/Controller.

You should see a Web page that boldly displays, "Greetings from MyEStore ControllerServlet". At this point, you have a stub version of your servlet. The final step is to copy the code from the examples above into your servlet code, recompile the servlet, and redeploy the servlet to the server.

Conclusion

This AppNote has shown how to design and implement the main pieces of your application that target the Web tier. You have properly structured the components and modules to allow your team of developers to focus on their areas of expertise. This ensures more robust results with a faster time-to-market.

In the next AppNote in this series, we will cross the chasm into the business tier and begin exploring some exciting technologies that will enable you to build a very sophisticated and powerful middleware service framework.

For Additional Information

For more information about the technologies discussed in this AppNote, refer to the following resources:

* Originally published in Novell AppNotes


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates