The rise of server-side Java applications—everything from standalone servlets to the full Java 2, Enterprise Edition (J2EE), platform—has been one of the most exciting trends to watch in Java programming. The Java language was originally intended for use in small, embedded devices. It was first hyped as a language for developing elaborate client-side web content in the form of applets. But until the last few years, Java’s potential as a server-side development platform had been sadly overlooked. Now, Java has come to be recognized as a language ideally suited for server-side development.
Businesses in particular have been quick to recognize Java’s potential on the server—Java is inherently suited for large client/server applications. The cross-platform nature of Java is extremely useful for organizations that have a heterogeneous collection of servers running various flavors of the Unix and Windows (and increasingly Mac OS X) operating systems. Java’s modern, object-oriented, memory-protected design allows developers to cut development cycles and increase reliability. In addition, Java’s built-in support for networking and enterprise APIs provides access to legacy data, easing the transition from older client/server systems.
Java servlets are a key component of server-side Java development. A servlet is a small, pluggable extension to a server that enhances the server’s functionality. Servlets allow developers to extend and customize any Java-enabled web or application server with a hitherto unknown degree of portability, flexibility, and ease. But before we go into any more detail, let’s put things into perspective.
While servlets can be used to extend the functionality of any Java-enabled server, they are most often used to extend web servers, providing a powerful, efficient replacement for CGI scripts. When you use a servlet to create dynamic content for a web page or otherwise extend the functionality of a web server, you are in effect creating a web application. While a web page merely displays static content and lets the user navigate through that content, a web application provides a more interactive experience. A web application can be as simple as a keyword search on a document archive or as complex as an electronic storefront. Web applications are being deployed on the Internet and on corporate intranets and extranets, where they have the potential to increase productivity and change the way that companies, large and small, do business.
To understand the power of servlets, we need to step back and look at some of the other approaches that can be used to create web applications.
The Common Gateway Interface, normally referred to as CGI, was one of the first practical techniques for creating dynamic content. With CGI, a web server passes certain requests to an external program. The output of this program is then sent to the client in place of a static file. The advent of CGI made it possible to implement all sorts of new functionality in web pages, and CGI quickly became a de facto standard, implemented on dozens of web servers.
It’s interesting to note that the ability of CGI programs to create dynamic web pages is a side effect of its intended purpose: to define a standard method for an information server to talk with external applications. This origin explains why CGI has perhaps the worst life cycle imaginable. When a server receives a request that accesses a CGI program, it must create a new process to run the CGI program and then pass to it, via environment variables and standard input, every bit of information that might be necessary to generate a response. Creating a process for every such request requires time and significant server resources, which limits the number of requests a server can handle concurrently. Figure 1-1 shows the CGI life cycle.
Even though a CGI program can be written in almost any language, the Perl programming language has become the predominant choice. Perl’s advanced text-processing capabilities are a big help in managing the details of the CGI interface. Writing a CGI script in Perl gives it a semblance of platform independence, but it also requires that each request start a separate Perl interpreter, which takes even more time and requires extra resources.
Another often-overlooked problem with CGI is that a CGI program cannot interact with the web server or take advantage of the server’s abilities once it begins execution, because it is running in a separate process. For example, a CGI script cannot write to the server’s log file. For more information on CGI programming, see CGI Programming on the World Wide Web by Shishir Gundavaram (O’Reilly).
A company named Open Market developed an alternative to standard CGI named FastCGI. In many ways, FastCGI works just like CGI—the important difference is that FastCGI creates a single persistent process for each FastCGI program, as shown in Figure 1-2. This eliminates the need to create a new process for each request.
Although FastCGI is a step in the right direction, it still has a problem with process proliferation: there is at least one process for each FastCGI program. If a FastCGI program is to handle concurrent requests, it needs a pool of processes, one per request. Considering that each process may be executing a Perl interpreter, this approach does not scale as well as you might hope. (Although, to its credit, FastCGI can distribute its processes across multiple servers.) Another problem with FastCGI is that it does nothing to help the FastCGI program more closely interact with the server. Finally, FastCGI programs are only as portable as the language in which they’re written. For more information on FastCGI, see http://www.fastcgi.com.
PerlEx, developed by ActiveState, improves the performance of CGI scripts written in Perl that run on Windows NT web servers (Microsoft’s Internet Information Server and iPlanet’s FastTrack Server and Enterprise Server). It has advantages and disadvantages similar to FastCGI. For more information on PerlEx, see http://www.activestate.com/plex.
If you are using the Apache web server, another option for improving CGI performance is using mod_perl. mod_perl is a module for the Apache server that embeds a copy of the Perl interpreter into the Apache executable, providing complete access to Perl functionality within Apache. The effect is that your CGI scripts are precompiled by the server and executed without forking, thus running much more quickly and efficiently. The downside is that the application can be deployed only on the Apache server. For more information on mod_perl, see http://perl.apache.org.
Several companies have created proprietary server extension APIs for their web servers. For example, iPlanet/Netscape provides an internal API called WAI (formerly NSAPI) and Microsoft provides ISAPI. Using one of these APIs, you can write server extensions that enhance or change the base functionality of the server, allowing the server to handle tasks that were once relegated to external CGI programs. As you can see in Figure 1-3, server extensions exist within the main process of a web server.
Because server-specific APIs use linked C or C++ code, server extensions can run extremely fast and make full use of the server’s resources. Server extensions, however, are not a perfect solution by any means. Besides being difficult to develop and maintain, they pose significant security and reliability hazards: a crashed server extension can bring down the entire server; a malicious server extension could steal user passwords and credit card numbers. And, of course, proprietary server extensions are inextricably tied to the server API for which they were written—and often tied to a particular operating system as well.
Microsoft has a technique for generating dynamic web content called Active Server Pages , or sometimes just ASP. With ASP, an HTML page on the web server can contain snippets of embedded code (usually VBScript or JScript—although it’s possible to use nearly any language). This code is read and executed by the web server before it sends the page to the client. ASP is optimized for generating small portions of dynamic content, using COM components to do the heavy lifting.
Support for ASP is built into Microsoft Internet Information Server Version 3.0 and above, available for free from http://www.microsoft.com/iis. Support for other web servers is available as a commercial product from Chili!Soft at http://www.chilisoft.com. Beware that ASP pages running on a non-Windows platform may have a hard time performing advanced tasks without the Windows COM library. For more information on programming Active Server Pages, see http://www.microsoft.com/workshop/server/default.asp and http://www.activeserverpages.com/.
JavaServer Pages , commonly called just JSP, is a Java-based alternative to ASP, invented and standardized by Sun. JSP uses a syntax similar to ASP except the scripting language is Java. Unlike ASP, JSP is an open standard implemented by dozens of vendors across all platforms. JSP is closely tied with servlets because a JSP page is transformed into a servlet as part of its execution. JSP is discussed in more detail throughout this book. For more information on JSP, see http://java.sun.com/products/jsp.
Enter Java servlets. As was said earlier, a servlet is a generic server extension—a Java class that can be loaded dynamically to expand the functionality of a server. Servlets are commonly used with web servers, where they can take the place of CGI scripts. A servlet is similar to a proprietary server extension, except that it runs inside a Java Virtual Machine (JVM) on the server (see Figure 1-4), so it is safe and portable. Servlets operate solely within the domain of the server: unlike applets, they do not require support for Java in the web browser.
Unlike CGI and FastCGI, which must use multiple processes to handle separate programs and/or separate requests, servlets can all be handled by separate threads within the same process or by threads within multiple processes spread across a number of backend servers. This means that servlets are also efficient and scalable. Because servlets run with bidirectional communication to the web server, they can interact very closely with the server to do things that are not possible with CGI scripts.
Another advantage of servlets is that they are portable: both across operating systems as we are used to with Java and also across web servers. As you’ll see shortly, all of the major web servers and application servers support servlets. We believe that Java servlets offer the best possible platform for web application development, and we’ll have much more to say about this later in the chapter.
Like Java itself, servlets were designed for portability. Servlets are supported on all platforms that support Java, and servlets work with all the major web servers. Java servlets, as defined by the Java Software division of Sun Microsystems (formerly known as JavaSoft), are an Optional Package to Java (formerly known as a Standard Extension). This means that servlets are officially blessed by Sun and are part of the Java language, but they are not part of the core Java API. Instead, they are now recognized as part of the J2EE platform.
To make it easy for you to develop servlets, Sun and
Apache have made available
the API classes separately from any web engine.
javax.servlet.http packages constitute this
Servlet API. The latest version of these classes is available for
download from http://java.sun.com/products/servlet/download.html. All
web servers that support servlets must
use these classes internally (although they could use an alternate
implementation), so generally this JAR file can also be found
somewhere within the distribution of your servlet-enabled web server.
It doesn’t much matter where you get the servlet classes, as long as you have them on your system, since you need them to compile your servlets. In addition to the servlet classes, you need a servlet runner (technically called a servlet container , sometimes called a servlet engine), so that you can test and deploy your servlets. Your choice of servlet container depends in part on the web server(s) you are running. There are three flavors of servlet containers: standalone , add-on, and embeddable.
A standalone servlet container is a server that includes built-in support for servlets. Such a container has the advantage that everything works right out of the box. One disadvantage, however, is that you have to wait for a new release of the web server to get the latest servlet support. Another disadvantage is that server vendors generally support only the vendor-provided JVM. Web servers that provide standalone support include those in the following list.
Apache’s Tomcat Server, the
official reference implementation for how a servlet container should
support servlets. Written entirely in Java, and freely available
under an open source license. All the source code is available and
anyone can help with its development. This server can operate
standalone or as an add-on providing Apache or other servers with
servlet support. It can even be used as an embedded container. Along
with Tomcat, Apache develops the standard implementation of the
javax.servlet.http packages. At the time of this
writing servlets are the only
javax.* packages officially maintained as open
source. See http://jakarta.apache.org.
iPlanet (Netscape) Web Server Enterprise Edition (Version 4.0 and later), perhaps the most popular web server to provide built-in servlet support. Some benchmarks show this server to have the fastest servlet implementation. Beware that, while Versions 3.51 and 3.6 of this server had built-in servlet support, those servers supported only the early Servlet API 1.0 and suffered from a number of bugs so significant the servlet support was practically unusable. To use servlets with Netscape 3.x servers, use an add-on servlet container. See http://www.iplanet.com.
Zeus Web Server, a web server some consider the fastest available. Its feature list is quite long and includes servlet support. See http://www.zeus.co.uk.
Caucho’s Resin, an open source container that prides itself on performance. It can run in standalone mode or as an add-on to many servers. See http://www.caucho.com.
Gefion Software’s LiteWebServer, a small (just over 100K) servlet container intended for uses, such as bundling with demos, where small size matters. See http://www.gefionsoftware.com/LiteWebServer.
World Wide Web Consortium’s Jigsaw Server, open source and written entirely in Java. See http://www.w3.org/Jigsaw.
Sun’s Java Web Server, the server that started it all. This server was the first server to implement servlets and acted as the effective reference implementation for Servlet API 2.0. It’s written entirely in Java (except for two native code libraries that enhance its functionality but are not needed). Sun has discontinued development on the server, concentrating now on iPlanet/Netscape products as part of the Sun-Netscape Alliance. See http://java.sun.com/products.
Application servers are a growing area of development. An application server offers server-side support for developing enterprise-based applications. Most Java-based application support servlets and the rest of the Java 2, Enterprise Edition, (J2EE) specification. These servers include:
BEA System’s WebLogic Application Server, one of the first and most famous Java-based application servers. See http://www.beasys.com/products/weblogic.
Orion Application Server, a high-end but relatively low-priced server, written entirely in Java. See http://www.orionserver.com.
Enhydra Application Server, an open source server from Lutris. See http://www.enhydra.org.
Borland Application Server 4, a server with a special emphasis on CORBA. See http://www.borland.com/appserver.
IBM’s WebSphere Application Server, a high-end server based partially on Apache code. See http://www-4.ibm.com/software/webservers.
ATG’s Dynamo Application Server 3, another high-end server written entirely in Java. See http://www.atg.com.
Oracle’s Application Server, a server designed for integration with an Oracle database. See http://www.oracle.com/appserver.
iPlanet Application Server, the J2EE-compliant big brother to the iPlanet Web Server Enterprise Edition. See http://www.iplanet.com/products/infrastructure/app_servers/nas.
GemStone/J Application Server, a Java server from a company previously known for its Smalltalk server. See http://www.gemstone.com/products/j.
Allaire’s JRun Server (formerly from Live Software), a simple servlet container that grew to an advanced container providing many J2EE technologies including EJB, JTA, and JMS. See http://www.allaire.com/products/jrun.
Silverstream Application Server, a fully compliant J2EE server that also started with a servlet focus. See http://www.silverstream.com.
An add-on servlet container functions as a plug-in to an existing server—it adds servlet support to a server that was not originally designed with servlets in mind or to a server with a poor or outdated servlet implementation. Add-on servlet containers have been written for many servers including Apache, iPlanet’s FastTrack Server and Enterprise Server, Microsoft’s Internet Information Server and Personal Web Server, O’Reilly’s WebSite, Lotus Domino’s Go Webserver, StarNine’s WebSTAR, and Apple’s AppleShare IP. Add-on servlet containers include the following:
New Atlanta’s ServletExec, a plug-in designed to support servlets on all the popular web servers on all the popular operating systems. Includes a free debugger. See http://www.servletexec.com.
Allaire’s JRun (formerly from Live Software), available as a plug-in to support servlets on all the popular web servers on all the popular operating systems. See http://www.allaire.com/products/jrun/.
The Java-Apache project’s JServ module, a freely available open source servlet container that adds servlet support to the extremely popular Apache server. Development has completed on JServ, and the Tomcat Server (acting as a plug-in) is the replacement for JServ. See http://java.apache.org/.
An embeddable container is generally a lightweight servlet deployment platform that can be embedded in another application. That application becomes the true server. Embeddable servlet containers include the following:
Apache’s Tomcat Server, while generally used standalone or as an add-on, this server also can be embedded into another application when necessary. Because this server is open source, development on most other embeddable containers has stopped.
Anders Kristensen’s Nexus Web Server, a freely available servlet runner that implements most of the Servlet API and can be easily embedded in Java applications. See http://www-uk.hpl.hp.com/people/ak/java/nexus/.
Before proceeding, we feel obliged to point out that not all servlet containers are created equal. So, before you choose a servlet container (and possibly a server) with which to deploy your servlets, take it out for a test drive. Kick its tires a little. Check the mailing lists. Always verify that your servlets behave as they do in the Tomcat reference implementation. Also, you may want to check what development tools are provided, which J2EE technologies are supported, and how quickly you can get a response on the support lines. With servlets, you don’t have to worry about the lowest-common-denominator implementation, so you should pick a servlet container that has the features you want.
For a complete, up-to-date list of available servlet containers, complete with current pricing information, see http://www.servlets.com.
So far, we have portrayed servlets as an alternative to other dynamic web content technologies, but we haven’t really explained why we think you should use them. What makes servlets a viable choice for web development? We believe that servlets offer a number of advantages over other approaches, including portability, power, efficiency, endurance, safety, elegance, integration, extensibility, and flexibility. Let’s examine each in turn.
Because servlets are written in Java and conform to a well-defined and widely accepted API, they are highly portable across operating systems and across server implementations. You can develop a servlet on a Windows NT machine running the Tomcat server and later deploy it effortlessly on a high-end Unix server running the iPlanet/Netscape Application Server. With servlets, you can truly “write once, serve everywhere.”
Servlet portability is not the stumbling block it so often is with applets, for two reasons. First, servlet portability is not mandatory. Unlike applets, which have to be tested on all possible client platforms, servlets have to work only on the server machines that you are using for development and deployment. Unless you are in the business of selling your servlets, you don’t have to worry about complete portability. Second, servlets avoid the most error-prone and inconsistently implemented portion of the Java language: the Abstract Windowing Toolkit (AWT) that forms the basis of Java graphical user interfaces, including Swing.
Servlets can harness the full power of the core Java APIs: networking and URL access, multithreading, image manipulation, data compression, database connectivity (JDBC), object serialization, internationalization, remote method invocation (RMI), and legacy integration (CORBA). Servlets can also take advantage of the J2EE platform that includes support for Enterprise JavaBeans (EJBs), distributed transactions (JTS), standardized messaging (JMS), directory lookup (JNDI), and advanced database access (JDBC 2.0). The list of standard APIs available to servlets continues to grow, making the task of web application development faster, easier, and more reliable.
As a servlet author, you can also pick and choose from a plethora of third-party Java classes and JavaBeans components. Servlets can use third-party code to handle tasks such as regular expression searching, data charting, custom database access, advanced networking, XML parsing, and XSLT translations.
Servlets are also well suited for enabling client/server communication. With a Java-based applet and a Java-based servlet, you can use RMI and object serialization in your client/server communication, which means that you can leverage the same custom code on the client as on the server. Using languages other than Java on the server side is much more complicated, as you have to develop your own custom protocols to handle the communication.
Servlet invocation is highly efficient. Once a servlet is loaded, it remains in the server’s memory as a single object instance. Thereafter, the server invokes the servlet to handle a request using a simple, lightweight method invocation. Unlike with CGI, there’s no process to spawn or interpreter to invoke, so the servlet can begin handling the request almost immediately. Multiple, concurrent requests are handled by separate threads, so servlets are highly scalable.
Servlets are naturally enduring objects. Because a servlet stays in the server’s memory as a single object instance, it automatically maintains its state and can hold on to external resources, such as database connections, that may otherwise take several seconds to establish.
Servlets support safe programming practices on a number of levels. Because they are written in Java, servlets inherit the strong type safety of the Java language. In addition, the Servlet API is implemented to be type-safe. While most values in a CGI program, including a numeric item like a server port number, are treated as strings, values are manipulated by the Servlet API using their native types, so a server port number is represented as an integer. Java’s automatic garbage collection and lack of pointers mean that servlets are generally safe from memory management problems like dangling pointers, invalid pointer references, and memory leaks.
Servlets can handle errors safely, due to Java’s exception-handling mechanism. If a servlet divides by zero or performs some other illegal operation, it throws an exception that can be safely caught and handled by the server, which can politely log the error and apologize to the user. If a C++-based server extension were to make the same mistake, it could potentially crash the server.
A server can further protect itself from servlets through the use of a Java security manager or access controller. A server can execute its servlets under the watch of a strict access controller that, for example, enforces a security policy designed to prevent a malicious or poorly written servlet from damaging the server filesystem.
The elegance of servlet code is striking.
Servlet code is clean, object oriented, modular, and amazingly
simple. One reason for this simplicity is the
API itself, which includes methods and classes to handle many of the
routine chores of servlet development. Even advanced operations, like
cookie handling and session tracking, are abstracted into convenient
classes. A few more advanced but still common tasks were left out of
the API, and, in those places, we have tried to step in and provide a
set of helpful classes in the
Servlets are tightly integrated with the server. This integration allows a servlet to cooperate with the server in ways that a CGI program cannot. For example, a servlet can use the server to translate file paths, perform logging, check authorization, and perform MIME type mapping. Server-specific extensions can do much of this, but the process is usually much more complex and error-prone.
The Servlet API is designed to be easily extensible. As it stands today, the API includes classes with specialized support for HTTP servlets. But at a later date, it could be extended and optimized for another type of servlets, either by Sun or by a third party. It is also possible that its support for HTTP servlets could be further enhanced.
Servlets are also quite flexible in how they create content.
They can generate simple content using
out.println( ) statements, or they can generate complicated sets of
pages using a template engine. They can create an
HTML page by treating the page as
a set of Java objects, or they can create an HTML page by performing
transformation. Servlets can even be built upon to create brand new
technologies like JavaServer Pages. Who knows what they (or you) will
up with next.
 Note that several web server vendors have their own server-side Java implementations, some of which have also been given the name servlets. These are generally incompatible with the Java servlets as defined by Sun. Most of these vendors are converting their Java support to standard servlets or are introducing standard servlet support in parallel, to allow backward compatibility.
 At one point it was planned for these classes to come bundled as part of JDK 1.2. However, it was later decided to keep the servlet classes separate from the JDK, to better allow for timely revisions and corrections to the Servlet API.
 Having a standard open source implementation
javax.servlet.http has resulted in numerous
helpful bug fixes (for example, Jason committed a fix to
HttpServlet improving the behavior of conditional
GET) and no incompatibility concerns. We hope this track record helps
encourage more official Java packages to be released as open