Jeeves

Java Servlet Application Programming Interface White Paper

Document Version: 0.45
August 2nd, 1996

This is a draft specification of the Java Servlet Application Programming Interface (API). This draft is being distributed for public review. Please send comments to jeeves@java.sun.com

Contents

Introduction

What are servlets?

Servlets are Java objects that extend the functionality of information servers, such as HTTP or Web servers. A plain HTML document that a Web server retrieves is static. A servlet, on the other hand, is executed for every request so that it can output dynamic information. For example, a browser generates a request to a server for a document that contains dynamic information. The server examines the request and maps it to a particular servlet. It then invokes the servlet which creates the document with dynamic content and returns it to the client.

Servlets can do more than just return documents. Once the HTTP connection is opened the client and servlet can speak a custom protocol on the connection. Servlets can be thought of as server side applets. The difference is that servlets are faceless objects without a user interface. Servlets can be long-lived. A new servlet does not have to be created for every request. The server just needs to call the servlet method that can respond to the request.

Servlets can be dynamically loaded in a running server. They can be loaded from the local disk or from the network. Agents are programs that can roam a network, interact with the host, gather information, and come to the host where they originated. Servlet technology is an important step forward in achieving this goal.

What is the servlet API?

The Java servlet application programming interface (API) is a standard for interfacing servlets with information servers, such as HTTP or Web servers. The servlet API contains methods for initializing a servlet, processing the request, getting servlet information, and destroying the servlet. The servlet API is simple, flexible, and stable. Application developers can write platform independent servlets and expect them to run on any server that supports the servlet API.

History

When the Web and HTTP servers became popular, the Common Gateway Interface (CGI) standard was devised for interfacing external applications with Web servers. A CGI application can be written in any language, for example C and PERL. CGI uses environment variables to send parameters to the application, for example QUERY_STRING and PATH_INFO. [1]. The two main drawbacks of using CGI are low performance (a new process has to be created for every request) and platform dependence. Also interaction between two CGI scripts running in the same server is complex.

FastCGI is an extension to CGI which uses persistent processes for for running external applications [2]. So a process does not have to be created for every request. But still the communication between the server and the application process can be slow since they are different processes.

To solve the performance problem C APIs were devised. The C modules run in the server process. For example, NSAPI, ISAPI The drawbacks of this approach are platform dependence, complexity, and lack of security.

Servlets solve the above problems and are flexible enough that you can write servlets to support applications written using the above approaches. For example one could write a FastCGIServlet which intercepts a request and communicates with the application using the FastCGI protocol.

Goals And Philosophy

Simplicity.
It should be easy to write servlets.
High performance.
Servlet startup overhead for every request should be avoided.
Platform independence.
Servlets should run in any server that supports the servlet API.
Industry standard.
The servlet API should become an industry standard.
Backward compatible.
The servlet API should be similar to the CGI interface in terms of naming.
Security and safety.
It should be possible to run untrusted servlets in servers.
Flexibility.
It should be possible for a single object to implement multiple interfaces and run in different servers. (?)

Overview Of The Major Interfaces And Classes

Servlets are objects that extend the Servlet class. The server uses the Servlet interface to exchange information with the servlets. The server passes objects that implement ServletRequest and ServletResponse to the servlet. The servlets use the ServletContext interface to exchange information with the server environment.

The server does the following:


		ServletContext
		* getServlets()
		* log(message)
			|
Server			|		Servlet
			|		* init()
			|		* serviceRequest(request, response)
			|

Design choices

Should we have generic java.servlet and HTTP specific java.servlet.http?
The trade-off is between flexibility of generic servlets vs ease-of-use for HTTP servlet writers. At this point in time we have decided to have only java.servlet. We need feedback on the requirements of servlets running in other servers.

Should we make Servlet a class or an interface?
There are three choices:

The advantage of providing a Servlet interface is that servlets do not have to extend a Servlet class. Any object can implement the Servlet interface. The disadvantage of providing only a Servlet class without an interface is that objects are forced to extend the Servlet class. The advantage of forcing people to use the Servlet class implementation is that we can add methods to the Servlet class without breaking existing servlets.

How much implementation should we provide in java.servlet?
Please send us your feedback.

Should ServletContext have a function to return the parent server?
If yes, what should be the type of the server object? Should it be "Object" or should we define an interface that all servers implement?

Do we need ServletStub?
The advantage of having ServletStub is that server implementations can add members to ServletStub implementations. It also makes the Servlet API more like the Applet API. On the other hand, if we pass ServletContext and Hashtable arguments to the servlet init method, ServletStub seems unnecessary.

How important is it to be similar to the Applet API?
In the Applet API, Applet is a class. The AppletStub interface is used. Please send us your feedback on this issue.

The java.servlet Package

Interfaces:

Classes:

The servlet API is changing. For the latest version of the API please see documentation generated by javadoc .

Servlet

The Servlet interface is implemented by objects that want to run in information servers and extend their functionality.

ServletContext

The ServletContext interface is used by a servlet uses to get information about its environment and send messages to its environment.

ServletRequest

The ServletRequest interface represents a servlet request. The server passes an object that implements ServletRequest to the service method of a servet. The servlet then uses this object to get information about the request.

This assumes that the URI used to invoke a servlet has the following form:
<protocol>://<host>:<port>/<servlet path><path info>?<query>

ServletResponse

The ServletResponse interface represents a servlet response. The server passes an object that implements ServletResponse to the service method of a servet. The servlet then uses this object to get respond to the request.

ServletStub

This interface is used by server implementors.

Security Considerations

The host server needs to ensure that a servlet does not compromise its security. In this section we describe one possible strategy which we have followed. We distinguish between two classes of servlets - trusted and untrusted. The decision to trust a servlet is up to the server. For example a server may decide to trust all local servlets and mistrust network servlets. Or it may decide to trust servlet that are signed by known entities.

Untrusted servlets are started in a separate threadgroup. The servlet security manager checks if the servlet is allowed to perform risky operations. Currently, there is no way in the java runtime to monitor the resource usage of a servlet.

Scenarios For Use

Accessing a database from a Web server.

Servlet initializes itself.
Request comes from client.
Server looks at the URL and invokes the servlet.
The servlet gets arguments from ServletRequest.
Connects to the database (using JDBC) gets the data and writes it using functions in ServletResponse.

Chat Servlet running in a Web server.

Servlet initializes itself.
Servlet is invoked for every connection from a client.
Servlet maintains a list of all connections in the chat room.
The connection is kept alive.
Server listens to each client connection and reflects the input to everyone else in the chat room.

Network loadable stock servlet

Client requests the Web server to upload a servlet from some URL.
The server gets the servlet class and creates a servlet object.
Servlet initializes itself.
The stock servlet gets real time data from a stock database and performs complex transformations on the data.
When a certain condition is satisfied it notifies the client.
The servlet could be signed if the operations on the database need to be protected.

Sample Servlet Code

SimpleServlet

SimpleServlet sends HTML text when it is invoked.

public class SimpleServlet extends Servlet { 

    public void service(ServletRequest req, ServletResponse res) {
        res.setStatus(SC_OK);
        res.setContentType("text/html");
        res.writeHeaders();
        PrintStream out = new PrintStream(res.getOutputStream());
        out.println("<HTML><HEAD>);
        out.println("<TITLE>SimpleServlet Output</TITLE>");
        out.println("</HEAD><BODY>");
        out.println("<H1>SimpleServlet Output</H1>");
        out.println("<P>This is output from SimpleServlet.");
        out.println("</BODY></HTML>");
    }

    public String getServletInfo() {
        return "A simple servlet";
    }

}

IsPrimeServlet

IsPrimeServlet takes in a number as input and checks if it is prime.

public class IsPrimeServlet extends Servlet {

    public void service(ServletRequest req, ServletResponse res) {
        Hashtable table = req.getQueryParameters();
        int number = Integer.parseInt(table.get("number"));
        boolean prime = isPrime(number);

        res.setStatus(SC_OK);
        res.setContentType("text/html");
        res.writeHeaders();
        PrintStream out = new PrintStream(res.getOutputStream());
        out.println("<HTML><HEAD>);
        out.println("<TITLE>IsPrimeServlet Output</TITLE>");
        out.println("</HEAD><BODY>");
        out.println("<H1>IsPrimeServlet Output</H1>");
        out.println("<P>");
        String output = "The number " + number + "is " +
            + prime?"":"not " + "prime.";
        out.println(output);
        out.println("</BODY></HTML>");
        out.flush();
        sc.log(this, output);
    }

    static boolean isPrime(int i) {  
        int j;  
        if ((i<=0) || (i==1)) { 
            return false; 
        } 
        for (j = 2; j < i; j++) { 
            if ((i % j) == 0) { 
                return false;  
            } 
        } 
        return true; 
    } 

    public String getServletInfo() {
        return "A servlet to test for primeness";
    }
 
}

References

[1]
D.R.T. Robinson. "The WWW Common Gateway Interface Version 1.1" Internet-Draft <draft-robinson-www-interface-01.txt>
[2]
"The FastCGI Specification" http://www.fastcgi.com/