Papers and Books

Java Servlets: Design Issues

Subbu Allamaraju.


Introduction

In the web-application server domain, Java servlets are fast replacing the CGI. By year 2000, most of the Java based application servers are expected to be based on Java servlets for connecting the middle-tier components with the HTML content (or templates).

This article is an extract of an internal development effort, during which the author happened to examine some of the development issues associated with developing small-to-medium scale web applications using Java Servlets.

This article does not intend to be a tutorial on how to program with Java servlets, although it covers the principal concepts associated with servlets. This article examines some of the design issues, and offers some guidelines on the applicability of Java servlets for web based application development. For a detailed tutorial on Java servlets, see the Tutorial on Servlet Essentials at http://www.novocode.com/doc/servlet-essentials.

Java Servlets

Java servlets are small, platform independent server-side programs that programmatically extend the functionality of the web server. The Java servlet API provides a simple framework for building applications on web servers. This API is described in the Java Servlet API Specification (currently version 2.1) by the Java Software Division of Sun Microsystems Inc.

Java servlets are not user-invocable applications. Servlets interact with a servlet engine (an implementation of the Java Servlet API specification) through requests and responses. The servlet engine in-turn interacts with the web server by delegating requests to servlets and transmitting responses to the web server.

When compared to the Common Gateway Interface (CGI) and proprietary server extensions such as Netscape Server API (NSAPI) or Microsoft's Internet Services API (ISAPI), servlets provide a better abstraction of the Hypertext Transfer Protocol (HTTP) request-response paradigm. In addition, servlets have all the advantages of the Java programming language, including platform independence. Java servlet based applications can be deployed on any web server with built-in (in-process) or connector-based (out-of-process) servlet engines, irrespective of the operating system and the hardware platform. This is one of the reasons for servlets gaining wide acceptance over the past one year.

Java Servlet Framework

In the HTTP based request-response paradigm, a client user agent (a web browser or any such application that can make HTTP requests and receive HTTP responses) establishes a connection with a web server and sends a request to the server. If the web server has a mapping to a servlet for the specified URL in the request, the web server delegates the request to the specified servlet. The servlet in turn processes the request and generates a HTTP response. For a description of the HTTP protocol and the request-response paradigm, see RFC-2068.

For web application development, the servlet API provides three primary abstractions: HTTP requests, request processing based on some application logic, and HTTP responses. These abstractions simplify the application development as far as the requests and responses are concerned. In addition, the servlet API also provides a mechanism for session tracking and state management. These are described below.

HTTP Request: The interface HttpServletRequest is the first abstraction provided by the servlet API. This interface encapsulates HTTP request from a user agent. When a request is received by the servlet engine, an object of this type is constructed and passed on to a servlet. This object provides methods for accessing parameter names and values of the request, other attributes of the request, and an input stream containing the body of the request.

HTTP Response: The HttpServletResponse interface of the servlet API provides an encapsulation of the HTTP response generated by a servlet. This interface defines an object created by the servlet engine that lets a servlet generate content in response to a user agent's request. This object provides methods to set type and length of the content, character encoding, cookies, response status including errors, and an output stream into which binary response data may be written. Alternatively, this object also provides a print writer object for writing formatted text responses.

Application Logic and Content Generation: The HttpServlet interface specifies methods for implementing the application logic and generating content in response to a HTTP request. These methods handle the GET, POST, HEAD, DELETE, OPTIONS, PUT and TRACE requests of HTTP. These methods are invoked by the servlet engine and act as placeholders for implementing application logic. The servlet engine also supplies HttpServletRequest and HttpServletResponse objects to these methods.

HTTP Servlet Framework
Figure 1: HTTP Servlet Framework

These interfaces are shown in Figure 1 in the context of a request and a response. In this diagram, the service method of the HttpServlet is shown to implement the application logic and content generation, although one of the doGet, doPost, doHead, doDelete, doOptions, doPut or doTrace methods can handle HTTP requests.

Session Tracking and State Management: The HTTP, which is the underlying protocol for web applications, is stateless. This protocol covers only a single request (with the connection initiated by the user agent) and a response. In this protocol, irrespective of the status of the protocol, the connection may be closed by either of the transacting parties. This has the following ramifications:

  • The protocol has no mechanism by which a series of unique requests from a user agent may be identified as being from the same user agent. Consequently, in a transaction spanning multiple requests and responses, the web server can not uniquely determine that all the requests are from the same user agent. A user, therefore, can not establish a dialog with the web server to perform a business transaction.
  • Since connections are not maintained by either of the transacting parties, the state of the transaction (and the application) can not be preserved across multiple requests.

The Java servlet API provides the HttpSession interface for session tracking and state management in a session. A servlet obtains a HttpSession object from the associated HttpServletRequest object. Servlets track sessions by URL rewriting or by cookies (See the tutorial on Servlet Essentials at http://www.novocode.com/doc/servlet-essentials for more details). Objects of type HttpSession can be set or obtained for new and existing sessions respectively from HttpServletRequest objects. Session specific data can be stored into these objects.

Application Development Issues

The Java servlet framework provides an object-oriented abstraction of the request-response routing model of CGI, and is well suited for gluing back-end applications to the web server. However, this framework is not adequate for object-oriented application development because of its inherent nature. This section examines the issues associated with servlet management, and some of the possible application architectures.

Servlet Management

Java servlets are server-side programs and are completely managed by the host servlet engine as described below:

  1. Servlets are managed by a host servlet engine. The servlet specification guarantees that a servlet is available for service against a request pointing to that servlet. However, there is no guarantee that the same instance of the servlet will be invoked against another identical request from the same or another user agent. There are several possibilities:
    • Based on some policy, the servlet engine might destroy and reinitialize a servlet between two consecutive and identical requests from the same or different user agents.
    • Alternatively, the servlet engine may maintain a pool of servlet instances and execute one of the free instances in the request thread.
    • The web server may have a load-balancing scheme under which identical requests to a servlet URI (Universal Resource Interface)) may invoke service methods of different servlet instances in different servlet engines running on two different platforms. Thus, identical requests may be serviced by different servlet instances in different Java virtual machines.
  2. Object references to servlets can be obtained by using the ServletContext (deprecated in version 2.1 of the Java Servlet API Specification), but not directly. This implies that objects should not hold references to instances of servlets, but should obtain them from the host servlet engine.
  3. Servlet methods can not be invoked with object references in the usual way. There are three ways in which a servlet can call methods of another servlet:
    • By specifying such methods to be "static."
    • By obtaining reference to a servlet as in (2) and then calling its methods. However, such instances can not maintain state in view of (1).
    • By forwarding the request and response objects to another servlet referenced by a URL (as of version 2.1 of the Java Servlet API Specification).
    • Alternatively, by including content generated by one servlet in the body of content generated by the calling servlet (as of version 2.1 of the Java Servlet API Specification).
  4. At any given instance, there can either be multiple instances of a servlet, or a single instance servicing multiple requests (in different service threads) or both. A servlet implementing the SingleThreadModel interface is an exception to this, in which case a servlet instance executes only one request at a time.

The following issues summarize the above discussion:

  1. Servlets are not reentrant programs, and therefore can not maintain state. HttpSession objects should be used to preserve state across multiple invocations of servlets. The application developer must explicitly determine the state attributes and store these in HttpSession objects. The servlet specification recommends that only serializable objects be stored into sessions. This is necessary to allow a servlet engine to serialize sessions either for load balancing or for memory management.
  2. Servlets may handle requests concurrently and must be ensured to be multi-thread safe. This precludes servlets having class-level attributes to hold application state.
  3. Servlets are completely managed by the host servlet engine, and inter-servlet communication is not equivalent to usual method invocation on objects.
  4. Objects implementing application logic can not maintain state unless these are maintained in HttpSession objects.
  5. Each servlet need to implement session tracking and state management explicitly.
  6. The bare-bones servlet API provides a simple abstraction over the traditional CGI model, but application developers need to leverage on the object-oriented features of the Java programming language to implement the application logic. However, this is not the natural servlet model.

Application Architecture

The following architectures are possible within the Java servlet framework.

Single-Tier Architecture:One of simplest approaches for servlet-driven web application development is based on the single-tier architecture. In this architecture, the application consists of a number of servlets each generating one or more web pages. The simplicity of this approach arises from the fact that there is often a one-to-one correspondence between a business transaction and a web page generated dynamically by the application. This usually leads to a one-to-one correspondence of a web page to a servlet generating that web page. The resulting architecture is shown in Figure 2. The arrows towards HTML pages indicate HTTP responses from servlets while the arrows in the reverse direction are HTTP requests.

Single-Tier Architecture
Figure 2: Single-Tier Architecture

Note that, in the cases of client-side programs (for example Java Applets or ActiveX components) in the generated content, this architecture may be treated as a two-tier architecture. Web browsers rendering plain HTML pages should not otherwise be considered to form the additional client-layer, since this approach does not actually partition the application.

Two-Tier Architecture: The single-tier architecture is not adequate for applications requiring data or services from additional servers. In this case, some or all the servlets need to connect to such back-end systems. This results in a two-tier architecture as shown in Figure 3. In this architecture, servlets act as gateways for the backend systems.

Two-Tier Architecture
Figure 3: Two-Tier Architecture

Three-Tier Architecture: This is the most common architecture for servlet based applications. In this architecture (shown in Figure 4), the application logic is implemented in a set of helper classes. Methods on objects of these classes are invoked by the service methods in the servlets.

Three-Tier Architecture
Figure 4: Three-Tier Architecture

If instances of helper classes contain session-specific state, such instances should be stored in session objects, as servlets can not hold references to such objects across multiple requests. This leads to breaking encapsulation of the application.

In all the above architectures, each servlet typically performs the following tasks:

  1. Session tracking: The first servlet establishes the session and the rest of the servlets in the application track the session either by cookies or by URL rewriting.
  2. State management, by storing pre-identified state of the application (including instances of helper objects, if necessary) in HttpSession objects associated with HTTP requests.
  3. Application logic, as necessary.
  4. In the case of a two-tier and three-tier architectures, connections to back-end systems for data or services.
  5. In the case of a three-tier architecture, invocation of methods on helper objects.
  6. Content generation.

Further, additional methods may be specified in servlet classes for performing application logic. In such cases, it is possible (with some constraints as discussed above) for a servlet to invoke these methods on other servlets.

Guidelines

Role of Servlets

While embarking web based application development based on Java servlets, it is necessary to recognize the fact that HTTP servlets provide an object-oriented abstraction of various HTTP requests. Servlets are not meant for enterprise-level application development.

Framework

Note that servlet instances are managed by a servlet engine. A servlet engine provides the necessary framework. As in the case of any framework, the developer must carefully examine the constraints associated, such as those mentioned above.

Databases

In an effort to "web-enable" databases, the most common practice (legacy from CGI!) is to obtain database connections (using JDBC) and to operate on databases. However, such an approach is not scalable and manageable. Here are some of the issues:

  • Connection Management: Since servlets do not maintain their own state, database connections can not be maintained across multiple execution of servlet methods. This necessitates an additional connection pooling layer. In general, any distributed application can gain significant performance improvements by pooling connections to servers.
  • Manageability: As is the case with typical two-tier architecture, knowledge of database tables and SQL gets spread across all the servlets in the application.

A good practice is to consider a separate layer to do most of the database-centric processing. However, not so surprisingly, most of the application servers (including the popular Netscape Application Server) encourage this style of programming in the name of RAD.

Application Logic

For scalability sake, servlets should not be used to process complex application logic. A good practice is to consider a distributed architecture, and move complex application logic into a separate layer of CORBA, RMI or EJB servers.

Conclusion

In the context of enterprise-level application development, servlets play a major role in providing the necessary glue between web servers and enterprise-wide components. However, servlets, on their own, are applicable only for small to medium scale application development.


© Subbu Allamaraju 1999. All rights reserved.

This document is protected by copyright. No part of this document may be reproduced in any form without prior written consent of the author. This document is for electronic distribution only.

All trademarks acknowledged.