Click on our Sponsors to help Support SunWorld

Servlets or CGI/Perl?

In this introduction to servlets, Java servlets and CGI/Perl technologies are compared in terms of performance, portability, and other key issues

By Craig Knudsen

December  1998
[Next story]
[Table of Contents]
Subscribe to SunWorld, it's free!

CGI (common gateway interface)/Perl has been around the block, so why would you want to use something else, like Java servlets? There are many issues to consider here, but it's undeniable that the use of servlets to implement Web-based applications has been growing in popularity. To find out why, Craig Knudsen compares CGI/Perl and Java servlet performance across the board. (2,200 words)

Mail this
article to
a friend

CGI has been the standard for developing interactive Web sites for what seems like an eternity. Although the CGI standard allows any language to be used, Perl is chosen the majority of the time. When I started developing Web sites a few years ago, the most advanced sites used CGI/Perl and flat files for data storage and retrieval. Today, I'm working with databases such as Oracle and Microsoft SQL Server and coding extensively in Java.

Servlets, 100 percent pure Java Web-based server applications, are an alternate solution to CGIs. Because servlets are compiled Java applications, they're portable across operating systems. Servlets require the Servlet API, which allows them to be used with almost any Web server. (It's technically possible to write a servlet in another programming language if you have a compiler that generates Java class files, but the end result would still be Java objects.)

So, is CGI/Perl still suited for today's increasingly complex Web sites?

Servlets vs. CGI/Perl
When deciding between CGI/Perl or servlets, the first question you might ask is "Can it do what I need it to do?" Then you might move on to "How hard will it be to implement?" The answers to these questions are often found in free and commercial add-ons for both CGI/Perl and servlets. Perl uses the concept of modules to add new capabilities. For instance, the DBI (database independent) interface module allows Perl scripts access to databases, including those of Oracle, Sybase, Ingres, and Informix. The CGI module includes functions for helping in CGI development, including routines for form variables, cookies, and sessions. All in all, hundreds of Perl modules are freely available from the Comprehensive Perl Archive Network (CPAN).

Java uses packages rather than modules. The Servlet API packages provide many of the same tools available in the Perl CGI module. For database access, JDBC (which is included with the JDK 1.1 release) can be used. Note that in addition to JDBC, you'll need a JDBC driver for your database. (See Sun's list of JDBC drivers in the Resources section below.) Many drivers, such as Sybase's jConnect and Oracle's JDBC Thin Driver, can be freely downloaded.

One of the most common complaints about CGI/Perl is its drain on system resources. In a typical CGI environment, each request creates a new process which then loads the Perl interpreter (typically over 500 KB in size). The Perl interpreter then loads the CGI script, compiles it, and executes it. Additionally, if the application communicates with a database, a new connection will need to be established for each CGI (a rather expensive process for some databases). Several solutions are available to help reduce the overhead of CGI/Perl. The mod_perl module for the Apache Web server links the Perl runtime library into the server. With mod_perl, it's not necessary for the Web server to start a new process for each request. FastCGI is another option, and it works with more Web servers than mod_perl.

Servlets start a new thread (rather than a new process) with each request. Each servlet is loaded once and used over and over. Note that unlike CGI, servlets require you to have a Java virtual machine (JVM) running on the server at all times. For busy sites, this allows servlets to use much less system resources, scale better, and provide improved performance.

Security can be a problem when developing CGIs. The largest area of concern is processing user input. This could be from forms or from data within the URL. Many CGIs written in Perl are vulnerable to attacks where the end user tricks the CGI into executing a command on the server. Servlets aren't at risk of running unintended shell commands. Compiled languages such as Java (or C) provide better security than interpreted scripting languages. (See the WWW Security FAQ's section on CGI scripts in the Resources section for more information on this.)

Are you installing the application on someone else's server? Servlets are compiled class files while CGI/Perl is delivered in its original source form. Depending on who has access to your Web server, you may prefer not to install source code.

Many sites are looking for a portable solution. Perhaps they want developers to use Linux or Windows NT while their production server runs Solaris. They may want to sell their Web application to as many customers on as many platforms as possible. There are versions of Perl for every variant of Unix as well as Windows 95 and NT. While Perl for Unix isn't 100 percent compatible with Perl for NT, CGIs written in Perl can be written to work on both. I've had to port CGIs to Windows NT on more than one occasion. It's not difficult to do, but the developer should be aware of this requirement beforehand. Otherwise, the CGI may contain Unix shell commands that won't work on Windows NT.

Portability with Java servlets is simpler. Java was designed to be portable across all platforms, allowing applications to be moved easily from one operating system to another.

Perl development is fairly simple. All you need is your favorite text editor and a lot of Perl documentation (available online). While many Perl developers feel most comfortable in this type of environment, there's a growing breed of IDE (integrated development environment) developers. In that arena, Java stands far above Perl. There are IDEs available from Sun, Microsoft, Symantec and many others, providing simple GUI-based build-and-debug environments. IDEs can provide useful time-saving tools and ease the learning curve for new developers. Of course, you can still use your favorite text editor with Java.

Sharing development among developers is also easier with Java. Developers can be assigned to develop individual packages. I've yet to work on a CGI/Perl application where two or more developers were working on the application simultaneously. The application is typically handed from one developer to another. Java application development scales better for large projects.

Debugging Web-based applications can be difficult. CGI/Perl is no exception. A runtime compile error will cause the CGI to abort, and the end user will either see Navigator's "Document contains no data" error message or a server error message. Older Web servers won't indicate where the Perl script aborted or what caused it. Newer Web servers will include the standard error output from the CGI in the server error log. This will typically indicate on what line and in which file the error occurred.

A servlet that generates an exception will be similarly logged on the server (depending on your servlet engine). For example, the following is from the servlet error log for a servlet that attempted to improperly access a null value:

        at HelloWorld.doGet(
        at javax.servlet.http.HttpServlet.service(
        at javax.servlet.http.HttpServlet.service(

Recently, I delivered a Web application written in Java. Soon after, I received an e-mail from a user, saying simply, "It doesn't work." Ordinarily, this type of message would leave me wondering why the user couldn't be a little more specific about the problem. But I wasn't worried. Because we had server logs for the Java application, I could clearly see where the error had occurred and what exception was generated. This was enough information for me to track down the problem.

Java also has remote debugging support. What does that mean for Web applications? If your servlet engine will allow you to pass the -debug option to the JVM and log its output (which includes the remote debugging password), you'll be able to attach a debugger (like the JDK's jdb) to your servlet engine and debug your servlets. This is a step up from CGI/Perl, which doesn't support any kind of interactive debugger.

Will your application continue to grow? I recently developed a tool for tracking projects and tasks using CGI/Perl and flat files. When more people started using the tool, it became too slow. When the company wanted an electronic timecard system integrated into the tool, I knew we had outgrown flat files. So, I converted the system from flat files to Oracle and DBI. This relieved some of the performance problems, but there are still some performance problems with many concurrent users. Why did I start with CGI/Perl and flat files? I chose CGI/Perl so that I could deliver a working application sooner. CGI/Perl is a wonderful tool for rapid prototypes. At the time, it wasn't clear how big the tool would get. Looking back, it might have been better to start with a servlet approach.


Servlet-enabled Web servers
You can run servlets by either obtaining a servlet-enabled server or by obtaining a server add-on that will run the servlets.

Sun's Java Web Server includes support for servlets without the need for a server add-on and also supports Java Server Pages (JSP), allowing you to embed Java code in static HTML pages. These pages are then compiled into servlets.

The more adventurous among you can freely download the Apache Web server and the mod_jserv module that supports servlets. Note that this isn't a point-and-click installation. You'll need to compile Apache and mod_jserv and edit Apache's configuration files.

Example: "Hello World" servlet
Writing your first servlet is very simple. Most servlets are a subclass of the HttpServlet class. Requests are processed through either the doGet() or the doPost() method. The following example displays an HTML page with nothing more on it than the words "Hello World."

import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {

  public void doGet (
    HttpServletRequest request,      // form variables, etc.
    HttpServletResponse response )   // methods for providing output
    throws ServletException, IOException {
    // set content type of HTTP header
    response.setContentType ( "text/html" );

    // create an output object and send our response
    PrintWriter out = response.getWriter ();
    out.println ( "<HTML><HEAD><TITLE>Hello World</TITLE></HEAD>\n" +
      "<BODY>Hello World!</BODY></HTML>" );
    out.close ();

In the interest of comparison, the example below shows how this would be done in CGI/Perl.

print "Content-type: text/html\n\n";
print "<HTML><HEAD><TITLE>Hello World</TITLE></HEAD>\n" .
  "<BODY>Hello World!</BODY></HTML>";
exit 0;

The Perl implementation takes fewer lines and can be written in less time. If this is all your application needs to do, you're probably better off with CGI/Perl. If your application needs to access a database, process HTML forms, or send e-mail, however, you'll need to consider other issues -- such as performance, portability, security, and how the Servlet API and add-on packages compare to available Perl modules for the functions you need.

The Servlet API
The Servlet API is contained within two packages:

Although the Servlet API is designed for use with HTTP, the separation into two packages allows the Servlet API to be extended to support alternate protocols. Today's servlets typically use mostly the HTTP-specific classes.

Servlet requests are processed through either the doGet() or the doPost() method. Both methods accept the HttpServletRequest and the HttpServletResponse object. Additionally, you can define init() and destroy() methods for when the servlet is first loaded and then unloaded. The same object instance may be used many times after being loaded. Initialization is a good time to set up database connections or perform other resource-intensive setup functions. Below is an overview of the most common methods of the HttpServletRequest, HttpServletResponse, HttpSession, and Cookie interfaces.

doGet() Called to handle HTTP GET requests
doPost() Called to handle HTTP POST requests
getCookies() Obtains array of cookies
getMethod() Returns the HTTP method (GET or POST)
getPathInfo() Returns any extra path information for the request URI
getRemoteUser() Gets the name of the user making the request (provided by HTTP authentication)
getSession() Returns the current valid session associated with this request or creates a new session
addCookie() Adds the specified cookie to the response
encodeURL() Encodes the URL by including the session id in it if needed
sendError() Sends an error response to the user with the specified error code
sendRedirect() Sends a redirect request to the user
getValue() Returns an object bound to the specified name for the session
putValue() Binds an object to the specified name for the session
removeValue() Removes an object bound to the specified name for the session
getName() Returns the name of the cookie
getValue() Returns the value of the cookie
setValue() Sets the value of the cookie

Java on the server
While applets certainly generated a lot of attention for Java, the server may be the best environment in which to deploy a Java solution. Java's advantages of code reuse, strict typing, portability, and performance can be particularly important to server applications. With the finalization of the Enterprise JavaBeans 1.0 Specification, more server-side Java solutions are on the way.

Sun is currently working on the JavaServer Pages Specification, which allows developers to embed Java within HTML files. The embedded Java code is compiled into servlets. Both Live Software's JRun and Net Atlanta's ServletExec support JavaServer Pages and servlets.

So what should you choose: CGI/Perl or servlets? That depends on what you're developing and how concerned you are about server load, scalability, security, portability, and growth potential. If you're building a small Web application that needs to be delivered quickly, you can stick with CGI/Perl. But if you're building a complex Web application that connects a database to your site, you may want to try a servlet implementation.

Click on our Sponsors to help Support SunWorld


Servlet information Running servlets CGI/Perl Information Other resources

About the author
Craig Knudsen has been developing Web-based solutions for four years with Perl, C, Java, and JavaScript. He maintains JavaWorld's Net News Central and telecommutes from Fairfax, VA as a Web engineer for ePresence, Inc. of Red Bank, NJ. Reach Craig at

What did you think of this article?
-Very worth reading
-Worth reading
-Not worth reading
-Too long
-Just right
-Too short
-Too technical
-Just right
-Not technical enough

[Table of Contents]
Subscribe to SunWorld, it's free!
[Next story]
Sun's Site

[(c) Copyright  Web Publishing Inc., and IDG Communication company]

If you have technical problems with this magazine, contact

Last modified: