Java Servlet Technology

Java Servlet - Background

Companies have to go for new and viable approaches to prolong their existence in the highly competitive market through the participation in the networked global economy. One interesting and highly beneficial way is to go for Web-enabling their applications. A major bottleneck for providing information over the Web for multiple devices is having to interface with legacy applications and databases. This bottleneck is due to the fact that many of those older applications or middleware implementations have not been implemented with the Web in mind.

Integrating these legacy systems may involve the complexity of the Java Native Interface (JNI) or the performance degradation of the Common Gateway Interface (CGI). In addition, performance is also one of the most important factors to be considered while integration. Applications such as e-commerce and financial systems needs always-on capability.

Having realised the ground reality, Sun Microsystems Ltd. has come out with the Java Servlet API that facilitates to develop robust, scalable, and portable Web applications. The Servlet API technology provides Web developers with a standard, simple, and consistent mechanism for extending the functionality of a Web server and for accessing existing business systems.

What is a Java Servlet

A servlet is a Java class that dynamically extends the function of a Web server. Java Servlets are small, platform-independent, server-side components coded fully using Java. Because it is written in Java, it has full access to Java's advanced features - database connectivity, network awareness, object orientation and built-in support for multi-threaded processes. These exciting features can be used to deliver full-functioned applications to Web clients without requiring any special client-side configuration. Because they use ordinary HTTP as their interface, they run the same in any browser environment.

A servlet runs in a Java virtual machine managed by a servlet engine. Like a CGI script, it is invoked to handle a request from a Web client, but unlike CGI, which requires a new process to be created for each request, a servlet remains loaded in the virtual machine, available to handle new requests. Each new request uses the same copy of the servlet in memory while running in its own thread of execution for optimal performance.

A servlet engine, which is typically a third-party add-on, is connected by some vendor-specific means to a Web server. The servlet engine intercepts specific HTTP requests that it recognizes as servlet requests. Other requests are handled by the Web server in its usual manner. The servlet engine loads the appropriate servlet if it is not already running and then assigns an available thread to handle the request, sending the servlet output back to the request client.

Servlets are the basic building blocks of web applications. A servlet has to implement the 'javax.servlet.Servlet' interface or to extend the abstract 'javax.servlet.http.HttpServlet' class. They fit seamlessly into the framework of application server and Web server and can be used to extend the capabilities of these servers in a variety of ways with minimal overhead, maintenance, and support. That is, instead of serving only static web pages, a servlet-enabled web server can invoke servlet methods to dynamically generate content at run time. The Java Servlet API provides a simple framework for building applications on Web servers.

Servlets for Generating Dynamic Web Pages

Java servlets allow application logic to be embedded in this HTTP request-response process. To know more about the role of application logic in this process, consider a web-based mail server. When we log into our favorite web-based mail server, the server should be able to send a page with links to our mail, our mail folders, our address book, etc. This information is dynamic, in the sense that each user expects to see their own mailbox. To generate such content, the server must execute complex application logic to retrieve our mail and compose a page to be delivered to us. While client can send client-specific or context information in the requests to the mail server, the server needs some mechanism to decide how the content should be generated.

HTTP does not define a standard means for embedding application logic during the response generation phase. There is no programming model specified for such tasks. HTTP defines how clients can request information and how servers can response but HTTP is not concerned with how the response could be generated. This is where server-side technologies such as Java servlets and Java Server Pages (JSP) come into the picture. With these technologies, we can embed custom application logic during one or more stages of the request processing and response generation

Java Servlet Engine

Java servlets are not user-invokable applications. Instead, the Web container, such as Jakarta TomCat, WebLogic, JRun etc., in which the Web application containing the servlets is deployed invokes the servlets. The web container providers implement most of the interfaces and classes of the Java Servlet API. When a servlet is being invoked, the Web container exchanges the incoming request information with the servlet, so that the servlet can analyze the incoming request, and generate responses dynamically. The Web container in turn interfaces with the Web server by accepting requests for servlets, transmitting responses back to the Web server.

There are a number of technologies for generating dynamic Web pages, such as CGI, NSAPI, ISAPI. But the servlet framework provides a better abstraction of the HTTP request-response paradigm by specifying a programming API for encapsulating requests, responses, sessions, etc. Notably, servlet instances can persist across client requests, so the server is not constantly spawning external processes. 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) Web containers, irrespective of the operating system and the hardware platform.

Servlet Implementation

When we write a servlet, we must either directly or indirectly implement the servlet interface that is, 'javax.servlet.Servlet'. This interface specifies the contract between the web container and a servlet. We will most likely always implement the interface indirectly by extending any one of the following classes: javax.servlet.GenericServlet and javax.servlet.http.HttpServlet. The interface contains five methods: init(), service(), destroy(), ServletConfig(), and getServletInfo().

The web container calls the init() method once the servlet has been instantiated. The purpose of this method is to allow a servlet perform any initialization required, before being invoked against HTTP requests. The container passes an object of type ServletConfig to the init() method. The init() method throws a ServletException in the event of the init() method not completing normally. This method will be called exactly only once on any given instance of the servlet and the init() method will be allowed to complete before any requests are passes to the servlet. Some of th primary tasks concerned with this method are reading configuration data from persistent resources such as configuration files, reading initialization parameters using the javax.servlet.ServletConfig object and initializing one-time activities such as registering a database driver, a connection pool or a logging service.

The service() method is called by the web container in response to incoming requests. This is the starting point for executing application logic in a servlet. This method will be called only after the init() method. This method accepts two arguments, implementing the javax.servlet.ServletRequest and javax.servlet.ServletResponse interfaces respectively.

The destroy() method is for destroying a servlet instance, which is out of service. This will become necessary for reclaiming some memory or if the web server is being shut down. This method will be called only after the servlet finishes execution of service and there is no request in the queue. Some of the activities that can be implemented in this method are performing cleanup tasks, such as unregistering a database driver, closing a connection pool, or even informing another application/system that the servlet will no longer be in service and persisting any state associated with a servlet.

The getServletConfig() method returns the ServletConfig object that was passed to the servlet during the initialization process. The getServletInfo() method will return a String object containing information about the servlet for example, author, creation date, description etc.

The GenericServlet class provides a basic implementation of the Servlet interface and it is an abstract class. All subclasses of this class should implement the service() method. This class has three methods: init(), log(String message) and log(String message, Throwable t) in addition to those declared in javax.servlet.Servlet and javax.servlet.ServletConfig interfaces. The GenericServlet class has to implement the methods of these interfaces.

The HttpServlet class extends GenericServlet and provides an HTTP-specific implementation of the Servlet interface. This class has service(), doGet(), doPost(), doDelete(), doOptions(), doPut() and doTrace() methods.

There are two service() methods. The first one casts the request and response objects to HttpServletRequest and HttpServletResponse and calls the second overloaded service() method. The overloaded method takes HTTP-specific request and response objects. The HttpServlet class implements the doXXX() methods, which stands for each of the HTTP request methods.

Servlet Configuration

In the Java Servlet API, javax.servlet.ServletConfig objects represent the configuration of a servlet. The configuration information contains initialization parameters, the name of the servlet, and a javax.servlet.ServletContext object, which gives the servlet information about the container. The initialization parameters and the name of a servlet can be specified in the deployment descriptor in XML.

The Servlet Lifecycle

We discuss here how a servlet interacts with a Web server via a Web container, which is a runtime that manages the servlets. Of the various responsibilities of a container, lifecycle management is the most crucial. The life cycle of a servlet contains the following stages: Instantiation, Initialization, Service, Destroy and Unavailable.

Firstly, a Web browser connects to a Web server and sends an HTTP request over the connection. Based on the request URL, the following sequence of events happens. The first thing the Web server has to do is to figure out if the incoming request corresponds to a Web application in the Web container. This needs an implicit understanding between the Web server and the Web container. Web containers use the notion of a servlet context to identify Web applications. We can specify the context when we are deploying the application onto the container.

Once the application figures out that the web container has to handle the request, the Web server delegates the request to the Web container. We can think of this process as the Web server invoking a local/remote method on the Web container, with the request information.

Once the Web container receives the request from the Web server, it should decide which application should handle this request. In a J2EE Web application, an HTTP request can be mapped to a servlet, or a JSP file, or any static resource based on URL patterns. Static resources include HTML/XML documents, images, applet class/JAR files, etc. These resources are part of the web application. When we package and deploy a Web application, we also specify this mapping information. The Web container uses this mapping information to map each incoming request to a servlet, a JSP, or a static resource. If the needed resource is mapped to a static resource, all that the Web container has to do is to pass that resource to the Web server and this forms the body of the response that the Web server sends to the Web browser.

Suppose if the Web container determines, based on the mapping information, that the request should be handled by a servlet, the Web container creates or locates a servlet instance, and delegates the request to the servlet instance in addition to the objects encapsulating the HTTP request and HTTP response. For a servlet instance, these objects represent the request and response streams from the browser. The servlet can read the request information, and write response to these streams. For writing response, the servlet can use the java.io.PrintWriter object associated with the response, and write content using println methods to the response. This is equivalent to writing content to the already opened connection from the Web browser.

The Java Servlet API

The Java servlet API is specified in two Java extension packages: javax.servlet and javax.servlet.http. Of these, in the javax.servlet package contains protocol independent classes and interfaces, while the second package javax.servlet.http contains classes and interfaces that are specific to HTTP. The Java servlet API provides two types of servlets.

Multi-threaded servlets - This is the most commonly used type of servlet. We can extend the 'javax.servlet.http.HttpServlet' class to implement our servlets that can handle multiple requests within a given servlet instance. In this model, the web container maintains a single instance of the servlet and direct all requests to the same instance in multiple threads. As long as the servlet instance is thread-independent without synchronized blocks and thread-unsafe code, this model provides the best possible throughput.

Single-thread servlets - This model is meant for servlets that are thread-sensitive. Servlets of this type implement the 'javax.servlet.SingleThreadModel' interface. This is a marker interface and does not specify any methods. When a servlet implements this interface, the web container makes sure that a given instance of this servlet handles one request at a time. To fulfill this, containers may follow one of the following approaches:

1. Instance Pooling - Here, the container maintains a pool of servlet instances. For each incoming request, the container allocates a servlet instance from the pool, and upon completion of the service, the container returns the instance to the pool.

2. Request Serialization - In this approach, the container maintains a single instance of the servlet. However, since the container can not send multiple requests to the instance at the same time, the container serializes the requests. This means that new requests will be kept awaiting while the current one is being executed.

It is better and prudent if both approaches are combined.

One of the common requirements for web applications is the ability to maintain client state across multiple requests. To accomplish this, the Java servlet API has come with the notion of session. An HTTP session is essentially an object associated with a given HTTP request. Servlets can store named objects in HTTP session objects and retrieve them when the need arises. Now another question comes into picture. how to maintain a session across multiple HTTP requests?. Web containers use either cookies or URL rewriting techniques to maintain sessions. When client browsers are not enabled to accept cookies, web containers has to use the URL rewriting mechanism.

In addition to maintain client-specific state, we can also maintain state common to all servlets in a given application, using the servlet context. Servlet context is common to all servlets within a web application. Also servlet context can be used to perform certain common tasks such as logging, and accessing application initialization parameters, among others.

Thus in order to develop and deploy a servlet based applications, first we have to code the servlet with the required application logic and provide a context and optional URL pattern mapping information during the deployment phase using a deployment descriptor coded in XML. This mapping information is being used in identifying the appropriate servlet from a Web application to service the request.

Advantages of Java Servlets

With so many choices for servers-side software development, one can wonder why Java servlet technology is superior to others. Server-side Java technologies give us platform independence, efficiency, access to other enterprise Java APIs, reusability, and modularity.

As Java servlets enjoy the same benefits of a regular Java program, they are platform-independent and can be ported across various platforms that support Java.

As compared with predecessors of Java servlet technology, Java servlets performs quite exceedingly well. Due to its distinct and unique multi-threading capability, it is possible for hundreds and even thousands of users can access the same servlet simultaneously without affecting the load of the web server.

Since servlets are an extension of the Java platform, they can access all of the Java APIs. A Java servlet can send and receive email, invoke methods of objects using Java RMI or CORBA, object directory information using the JNDI package, make use of an Enterprise JavaBean (EJB), or may other part of the ever-growing platform.

Software reusability is the essential mantra for software development. As servlets are web components, they can be reused easily. Also Java, as an OO language, helps to encapsulate shared functionality to be reused. Thus Java servlets are reusable.

When developing server-side software applications, its size becomes larger and automatically complexity intrudes in. It is always helpful if such a large application gets broken into discreet modules that are each responsible for a specific task. This divide and conquer principle helps to maintain and understand easily. Java servlets provide a way to modularize our application.

C++ Implementation of the Java Servlet API C++ programmers have limited options for bringing their applications to the Web: Java Servlets combined with JNI, CGI or a proprietary Web server's API. To overcome this deficiency, RogueWave came a C++ implementation of the Java Servlet API and it is called as Bobcat. This C++ implementation builds on the core RogueWave C++ product line and provides a highly efficient, scalable, robust and very portable Servlet API written entirely in C++. Bobcat provides a better way of integrating C++ with the Web than CGI. Also, they are compiled and hence C++ servlets provide up to 30% better performance than Java.

Click for Java Servlets - Links


Back to my Home Page