Java software has quickly become a part of the Web experience. Webmasters frequently use applets to liven up Web pages and make them interactive. There are applet news-tickers, animated eye-candy, and even entire games. Today, Java applets are used everywhere, but when they were first introduced, the idea was revolutionary. Applets quickly took the Web by storm, and offered users a greater degree of interaction with sites. Despite all their advantages, however, client-side execution of Java code has faced problems. In terms of performance, Java applets are often slow to load and execute over the network. They are also limited by network security restrictions imposed by the browser. These restrictions prevent applets from making connections to any other machine than the one from which they were loaded. These issues have limited, to some degree, the amount of freedom developers have when creating Java software.
Now imagine, for a moment, an environment where Java code loads quickly and effortlessly. Imagine an environment where there are no security restrictions, and Java applications can establish network connections to wherever they choose. Such an environment quickly springs to mind for those who do server-side development with CGI scripts or Active Server Pages — no browser restrictions, no delays in loading large numbers of classes. That’s the vision behind the Java Servlet technology — empowering Java software by allowing it to execute on Web servers.
Learning about servlets
Servlets are applications, written in Java, that are executed similar to the way a CGI script runs on a Web site. Servlets have become an extension to Java, and are defined in the javax.servlet and javax.servlet.http packages, which come with Sun’s Servlet Development Kit. This kit contains an implementation of the servlet extensions, as well as documentation and tools necessary for development.
Servlets running on Web servers are usually classes that are extended from javax.servlet.http.HttpServlet, which is in turn extended from GenericServlet, which implements a servlet interface. Figure 1 shows the inheritance relationship between GenericServlet and HTTPServlet. By overriding certain methods, developers can provide custom functionality for specific requests. For example, to accept data from an HTML form that uses the POST request method, a developer could override the
doPost()method. It is also common to override the
init()and
destroy()methods, to provide initialization and destruction handlers.
Figure 1. Inheritance relationship between GenericServlet and HttpServlet, with most commonly overridden methods highlighted (*) |
Creating servlets
Servlets are extremely easy to write. Unlike many scripting languages that are used for CGI, there is no need to develop custom code to parse HTTP requests or parameters. You simply extend HttpServlet, implement the request methods you want your servlet to support, then compile and deploy the servlet to a Web server.
Let’s look at a practical example and consider a simple servlet that responds to a GET request. We start by importing the javax.servlet extensions, as well as the java.io package, which provides us with access to Reader & Writer classes.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
Next, we declare a new public class that extends HttpServlet. We must provide a default constructor, even if the constructor performs no actual work. Without a public default constructor, some servlet engines have difficulty instantiating the servlet.
public class MyFirstServlet extends HttpServlet
{
// Provide a default constructor
public MyFirstServlet()
{
}
}
Finally, we must provide an implementation for HTTP GET requests, by overriding the
doGetmethod. Note that two parameters are passed to this method, of type HttpServletRequest and HttpServletResponse. The former allows us easy access to parameters passed to the Java servlet, and the latter offers a mechanism for sending information as output.
Listing 1: Providing an implementation for HTTP GET requests, by overriding the doGet method.
by David Reilly.
// Implement a "GET" request public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // Set MIME content-type for a HTML response res.setContentType("text/html");</pre> <pre> // Obtain a print writer to output our message PrintWriter out = res.getWriter();</pre> <pre> // Output Hello World!, and close writer out.println("<H1><FONT COLOR='blue'>Hello World</FONT></H1>"); out.close(); } |
In this example, the servlet assigns a MIME content type of text/html — indicating that HTML markup will be returned. Our servlet outputs a response, which is the obligatory "Hello World" message, and then closes the output writer. Note that virtually any type of content could be delivered by a servlet, including text and binary data. We could, for example, output the same message in text, simply by changing the parameter passed to
setContentType().
// Implement a "GET" request
public void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
// Set MIME content-type for a text response
res.setContentType("text/plain"); // Obtain a print writer to output our message
PrintWriter out = res.getWriter(); // Output a text message
out.println("Hello World");
out.close();
}
Figure 2 shows the output of MyFirstServlet in HTML format, and Figure 3 shows the output when plain text is used.
Figure 2. HTML output of servlet |
Deploying a servlet
Many commercial Web servers include support for Java servlets, and the number that do is growing. However, for those developers who use older Web servers and cannot upgrade to a more current version, there are several options available. For servers that support CGI, a servlet engine can be used. The engine can act as a wrapper between the server and the servlet. Another alternative that is particularly attractive for development and testing of servlets is to use the servletrunner application, which ships with the Java Servlet Development Kit.
Servletrunner is a small, multi-threaded Web server that makes it easy to test and debug servlets. In a pinch, it can even be used in conjunction with an existing Web server — servletrunner allows you to specify an alternative port on which to run the service.
Deploying servlets with servletrunner is a snap. Once you’ve installed the JSDK, you’ll find an examples directory with some sample servlets. Each servlet is associated with a name, so that client applications can invoke the servlet. To add new servlets, simply follow these steps:
- Compile your servlet
- Copy the class file for the servlet into the JSDKexamples directory
- Modify the JSDKexamplesservlet.properties file to map your servlet to a name.
For example, to install MyFirstServlet, a new line would be added to the servlet.properties file naming the servlet.
# My First Servlet will be known as first
servlet.first.code=MyFirstServlet
Once the servlet is named, and the the servletrunner application (located in the JSDKbin directory) is running, it can be invoked by a Web browser. For example, if servletrunner was using the default port of 8080, the URL would be http://localhost:8080/servlet/first/
Summary
The power and versatility of server-side Java makes servlets an excellent alternative to CGI scripting or Active Server Pages (ASP). It’s also very easy to get up to speed with servlets. Not only can existing Java code and experience be leveraged, but Java also offers significant advantages over other server-side mechanisms. In the next part of this tutorial [in two weeks], you’ll learn more about multi-threaded servlet programming and the advantages this offers developers, as well as how to write interactive servlets that respond to user data from HTML forms.
Code for this article
Resources
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;//
//
// MyFirstServlet
//
//
public class MyFirstServlet extends HttpServlet
{
// Provide a default constructor
public MyFirstServlet()
{}
// Implement a “GET” request
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
// Set MIME content-type for a HTML response
res.setContentType(“text/html”);// Obtain a print writer to output our message
PrintWriter out = res.getWriter();// Output HTML message
out.println(“Hello World
“);
out.close();
}// Return name of servlet
public String getServletInfo()
{
return “My First Servlet”;
}
}
About the author
David Reilly is a software engineer and freelance technical writer living in Australia. A Sun Certified Java 1.1 Programmer, his research interests includes the Java programming language, and networking & distributed systems. He can be reached via e-mail at java@davidreilly.com.