How Tomcat Works

The HttpServer Class

The HttpServer class represents a web server and is presented in Listing 1.1. Note that the await method is given in Listing 1.2 and is not repeated in Listing 1.1 to save space.

Listing 1.1: The HttpServer class

pakage ex01.pyrmont;

import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.File;
public class HttpServer {
/** WEB_ROOT is the directory where our HTML and other files reside.
 * For this package, WEB_ROOT is the "webroot" directory under the
 * working directory.
 * The working directory is the location in the file     system
 * from where the java command was invoked.
 */
    public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot";
    // shutdown command
    private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
    // the shutdown command received
    private boolean shutdown = false;
    public static void main(String[] args) {
        HttpServer     server = new HttpServer();
        server.await();
    }
    public void await() {
        ...
    }
}

Listing 1.2: The HttpServer class's await method

public void await() {
    ServerSocket serverSocket = null; int port = 8080;
    try {
        serverSocket = new ServerSocket(port, 1,InetAddress.getByName("127.0.0.1"));
    } catch (IOException e) {
        e.printStackTrace();
        System.exit(1);
    }
    // Loop waiting for a request
    while (!shutdown) {
        Socket socket = null;
        InputStream input = null;
        OutputStream output = null;
        try {
            socket = serverSocket.accept();
            input = socket.getInputStream();
            output = socket.getOutputStream();
            // create Request object and parse
            Request request = new Request(input);
            request.parse();
            // create Response object
            Response response = new Response(output);
            response.setRequest(request);
            response.sendStaticResource();
            // Close the socket socket.close();
            //check if the previous URI is a shutdown command
            shutdown = request.getUri().equals(SHUTDOWN_COMMAND); }
        catch (Exception e) {
            e.printStackTrace ();
            continue;
        }
    }
}

This web server can serve static resources found in the directory indicated by the public static final WEB_ROOT and all subdirectories under it. WEB_ROOT is initialized as follows:

public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot";

The code listings include a directory called webroot that contains some static resources that you can use for testing this application. You can also find several servlets in the same directory for testing applications in the next chapters.

To request for a static resource, you type the following URL in your browser's Address or URL box:

http://machineName:port/staticResource

For instance, if you are using the same computer to test the application and you want to ask the HttpServer object to send the index.html file, you use the following URL:

http://localhost:8080/index.html

To stop the server, you send a shutdown command from a web browser by typing the pre-defined string in the browser's Address or URL box, after the host:port section of the URL. The shutdown command is defined by the SHUTDOWN static final variable in the HttpServer class:

private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";

Therefore, to stop the server, you use the following URL:

http://localhost:8080/SHUTDOWN

Now, let's look at the await method printed in Listing 1.2.

The method name await is used instead of wait because wait is an important method in the java.lang.Object class for working with threads.

The await method starts by creating an instance of ServerSocket and then going into a while loop.

serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
...
// Loop waiting for a request
while (!shutdown) {
...
}

The code inside the while loop stops at the accept method of ServerSocket, which returns only when an HTTP request is received on port 8080:

socket = serverSocket.accept();

Upon receiving a request, the await method obtains java.io.InputStream and java.io.OutputStream objects from the Socket instance returned by the accept method.

input = socket.getInputStream();
output = socket.getOutputStream();

The await method then creates an ex01.pyrmont.Request object and calls its parse method to parse the HTTP request raw data.

// create Request object and parse
Request request = new Request(input);
request.parse ();

Afterwards, the await method creates a Response object, sets the Request object to it, and calls its sendStaticResource method.

// create Response object
Response response = new Response(output);
response.setRequest(request);
response.sendStaticResource();

Finally, the await method closes the Socket and calls the getUri method of Request to check if the URI of the HTTP request is a shutdown command. If it is, the shutdown variable is set to true and the program exits the while loop.

// Close the socket socket.close ();
//check if the previous URI is a shutdown command
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);