CSCI A348/548
Lecture Notes Nineteen

Fall 2000


Java Servlets. (Please see the companion lab notes as well).

The Java Servlet API provides a standard way to extend the functionality of any kind of server that uses a protocol based on requests and responses.

Servlets are used primarily with web servers, where they provide Java-based replacement for CGI scripts.

In other words, on a web server that supports servlets (and there are many), you can use a Java servlet to create dynamic web content in much the same way you currently use a CGI script.

Servlets have many advantages over CGI scripts, however:

  1. For example, servlets are persistent between invocations, which dramatically improves performance relative to CGI programs.

  2. Servlets are also portable among operating systems and among servers.

  3. Servlets have access to all the APIs of the Java platform so, for example, it is easy to create a servlet that interacts with a database, using the JDBC API.

In terms of enterprise (or distributed) computing, servlets are a natural fit if you are using the web as your development platform.

  1. You can take advantage of web browsers as universally available thin clients;

  2. the web server becomes middleware that is responsible for running applications for these clients.

  3. Under this model,

  4. What's key here is that the servlet can use JNDI, Java IDL, and other Java Enterprise APIs to perform whatever tasks are necessary to fulfill the request.

The Servlet Life Cycle

When a client makes a request involving a servlet, the server loads and executes the appropriate Java classes. Those classes generate content, and the server sends the content back to the client. In most cases, the client is a web browser, the server is a web server, and the servlet returns standard HTML. On the server side, however, there is one important difference: persistence.

Note however that persistence is used here to mean "enduring between invocations," and not "written to permanent storage," as it is sometimes used.

Instead of shutting down at the end of each request,the servlet can remain loaded, ready to handle subsequent requests.

The request processing time for a servlet can vary, but it is typically quite fast when compared with a similar CGI program. The real advantage of a servlet, however, is that you incur most of the startup overhead only once.

When a servlet loads, its init() method is called.

You can use init() to create I/O intensive resources, such as database connections, for use across multiple invocations. If you have a high-traffic site, the performance benefits can be quite dramatic. Instead of putting up and tearing down a hundred thousand database connections, the server needs to create a connection only once. The servlet's destroy() method can clean up resources when the server shuts down.

Because servlets are persistent, you can actually remove a lot of filesystem (and/or database) accesses altogether. For example to implement a page counter, you can simply store a number in a static variable rather than consulting a file (or a database) for every request. Using this technique, you need to read and write to the disk only occasionally to preserve state.

Since a servlet remains active, it can perform other tasks when it is not servicing client requests, such as running a background processing thread (where clients connect to the servlet to view the result) or even acting as an RMI host, enabling a single servlet to handle connections from multiple types of clients. For example, if you write an order processing servlet, it can accept transactions from both an HTML form and an applet using RMI.

Servlet Basics

The Servlet API consists of two packages:

The javax part is there because servlets are a standard eXtension to Java, rather than a mandatory part of the API.

This means that while servlets are official Java, Java virtual machine developers are not required to include the classes for them in their Java development and execution environments.

The three core elements of the Servlet API are:

Normally, you create a servlet by subclassing one of the two classes, although if you are adding servlet capability to an existing object, you may find it easier to implement the interface.

The GenericServlet class is used for servlets that do not implement any particular communication protocol. Here's a basic servlet that demonstrates servlet structure by printing a short message.

burrowww.cs.indiana.edu% cd
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman
burrowww.cs.indiana.edu% cd $myServlets
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% cat L19BasicServlet.java
import javax.servlet.*;
import java.io.*;
       
public class L19BasicServlet extends GenericServlet {
  public void service(ServletRequest  req, 
                      ServletResponse resp) throws  ServletException,  
                                                    IOException { 
    resp.setContentType("text/plain"); 
    PrintWriter out = resp.getWriter();
    out.println("Hello, this is L19."); 
  }
}
We compile it:
burrowww.cs.indiana.edu% javac L19BasicServlet.java
burrowww.cs.indiana.edu% ls -l L19Basi*
-rw-r--r--   1 dgerman  students      671 Oct 31 00:19 L19BasicServlet.class
-rw-r--r--   1 dgerman  students      414 Oct 30 22:58 L19BasicServlet.java
-rw-r--r--   1 dgerman  students      398 Oct 30 22:53 L19BasicServlet.java~
burrowww.cs.indiana.edu%
And we check it from
http://burrowww.cs.indiana.edu:12xxx/examples/servlet/L19BasicServlet
BasicServlet extends the GenericServlet class and implements one method: service().

Whenever a server wants to use the servlet,

The servlet tells the server what type of response to expect, gets a printWriter from the response object, and transmits its output.

More Examples

1. The first servlet we develop is a very generic and simple one.

burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% cat L19_S1.java
import javax.servlet.*;
import java.io.*; 
       
public class L19_S1 extends GenericServlet {
  public void service(ServletRequest req, ServletResponse resp)
       throws ServletException, IOException { 
    resp.setContentType("text/plain"); 
    resp.getWriter().println("Hello... L19_S1 here!"); 
  } 
} 
burrowww.cs.indiana.edu% javac L19_S1.java
burrowww.cs.indiana.edu% 
2. The second servlet we develop is an HTTP Servlet, a more specific one.
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% ls -ld L19_S2.java
-rw-r--r--   1 dgerman  students      467 Oct 31 00:42 L19_S2.java
burrowww.cs.indiana.edu% cat L19_S2.java
import javax.servlet.*; 
import javax.servlet.http.*;
import java.io.*;
       
public class L19_S2 extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse resp) 
       throws ServletException, IOException {
    resp.setContentType("text/html"); 
    resp.getWriter().println(
        "<html><head><title>L19_S2</title></head><body bgcolor=white>"
      + "HttpServlet replying to GET with: L19_S2 here!</body></html>"
    ); 
  } 
} 

burrowww.cs.indiana.edu% javac L19_S2.java
burrowww.cs.indiana.edu% 
3. The third servlet we develop is processing a form request.
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/jakarta-tomcat/webapps/examples/WEB-INF/classes
burrowww.cs.indiana.edu% ls -ld L19_S3.java
-rw-r--r--   1 dgerman  students      964 Oct 31 00:48 L19_S3.java
burrowww.cs.indiana.edu% cat L19_S3.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
       
public class L19_S3 extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse resp)
       throws ServletException, IOException {
    resp.setContentType("text/html"); 
    resp.getWriter().println(
       "<html><head><title>L19_S3 GET</title></head><body bgcolor=white>"
     + "<form method=POST action=/examples/servlet/L19_S3>Type your name here: " 
     + "<input type=text name=namefield size=10> <p> then push <input " 
     + " type=submit value=Proceed> (or hit Enter) </form></body></html>"
    ); 
  } 
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
       throws ServletException, IOException {
    resp.setContentType("text/html"); 
    resp.getWriter().println(
       "<html><body bgcolor=white><h1>Hello, <font color=blue>" 
     + req.getParameter("namefield")
     + "</font>!</h1></body></html>"
    ); 
  } 
} 

burrowww.cs.indiana.edu% javac L19_S3.java
burrowww.cs.indiana.edu% 
In class we will compare these with CGI implementations.

The Chat Server

We'll introduce the problem in class and sketch a few solutions to it.

On Thursday we will discuss one such solution in detail.


Last updated on October 30, 2000, by Adrian German for A348/A548.