How Tomcat Works

The Response Class

The ex01.pyrmont.Response class represents an HTTP response and is given in Listing 1.6.

Listing 1.6: The Response class

package ex01.pyrmont;

import java.io.OutputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.File;

/*
HTTP Response = Status-Line
*(( general-header | response-header | entity-header ) CRLF)
CRLF
[ message-body ]
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
*/

public class Response {
    private static final int BUFFER_SIZE = 1024;
    Request request;
    OutputStream output;
    public Response(OutputStream output) {
    this.output = output;
    }
    public void setRequest(Request request) {
    this.request = request;
    }
    public void sendStaticResource() throws IOException {     byte[] bytes = new byte[BUFFER_SIZE];
    FileInputStream fis = null;
    try {
        File file = new File(HttpServer.WEB_ROOT, request.getUri());
        if (file.exists()) {
        fis = new FileInputStream(file);
        int ch = fis.read(bytes, 0, BUFFER_SIZE);
        while (ch!=-1) {
            output.write(bytes, 0, ch);
            ch = fis.read(bytes, 0, BUFFER_SIZE);
            }
    } else {
    // file not found
        String errorMessage = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 23\r\n" +"\r\n" +"<\h1>File Not Found<\/h1>";
        output.write(errorMessage.getBytes());
    } }catch (Exception e) {
    // thrown if cannot instantiate a File object
    System.out.println(e.toString() );
    } finally {
        if (fis!=null) fis.close();
    } }
}

First note that its constructor accepts a java.io.OutputStream object, such as the following.

public Response(OutputStream output) {
    this.output = output;
}

A Response object is constructed by the HttpServer class's await method by passing the OutputStream object obtained from the socket.

The Response class has two public methods: setRequest and sendStaticResource method. The setRequest method is used to pass a Request object to the Response object.

The sendStaticResource method is used to send a static resource, such as an HTML file. It first instantiates the java.io.File class by passing the parent path and child path to the File class's constructor.

File file = new File(HttpServer.WEB_ROOT, request.getUri());

It then checks if the file exists. If it does, sendStaticResource constructs a java.io.FileInputStream object by passing the File object. Then, it invokes the read method of the FileInputStream and writes the byte array to the OutputStream output. Note that in this case the content of the static resource is sent to the browser as raw data.

if (file.exists()) {
    fis = new FileInputstream(file);
    int ch = fis.read(bytes, 0, BUFFER_SIZE);
    while (ch!=-1) {
        output.write(bytes, 0, ch);
        ch = fis.read(bytes, 0, BUFFER_SIZE);
    }
}

If the file does not exist, the sendStaticResource method sends an error message to the browser.

String errorMessage = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n" +"Content-Length: 23\r\n" + "\r\n" + "<h1>File Not Found</h1>";
output.write(errorMessage.getBytes());