ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

How Servlet Containers Work
Pages: 1, 2, 3, 4

The HttpServer1 Class

The HttpServer1 class in this application is similar to the HttpServer class in the simple web server application in the previous article. However, in this application, the HttpServer1 can serve both static resources and servlets. To request a static resource, use a URL in the following format:



http://machineName:port/staticResource

This is exactly how you requested a static resource in the web server application in the previous article. To request a servlet, you use the following URL:

http://machineName:port/servlet/servletClass

Therefore, if you are using a browser locally to request a servlet called PrimitiveServlet, enter the following URL in the browser's address or URL box:

http://localhost:8080/servlet/PrimitiveServlet

The class' await method, given in Listing 2.2, waits for HTTP requests until a shutdown command is issued. It is similar to the await method discussed in the previous article.

Listing 2.2. The HttpServer1 class' 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);

            // check if this is a request for a servlet or a static resource
            // a request for a servlet begins with "/servlet/"
            if (request.getUri().startsWith("/servlet/")) {
                ServletProcessor1 processor = new ServletProcessor1();
                processor.process(request, response);
            }
            else {
               StaticResourceProcessor processor =
                   new StaticResourceProcessor();
               processor.process(request, response);
            }

            // 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();
            System.exit(1);
        }
    }
}

The difference between the await method in Listing 2.2 and the one in the previous article is that in Listing 2.2, the request can be dispatched to either a StaticResourceProcessor or a ServletProcessor. The request is forwarded to the latter if the URI contains the string "/servlet/." Otherwise, the request is passed to the StaticResourceProcessor instance.

The Request Class

A servlet's service method accepts a javax.servlet.ServletRequest instance and a javax.servlet.ServletResponse instance from the servlet container. The container therefore must construct a ServletRequest object and a ServletResponse object to pass to the service method of the servlet being served.

The ex02.pyrmont.Request class represents a request object to pass to the service method. As such, it must implement the javax.servlet.ServletRequest interface. This class has to provide implementations for all methods in the interface. However, we'd like to make it very simple and implement only a few of the methods. To compile the Request class, you'll need to provide blank implementations for those methods. If you look at the Request class, you can see that all methods whose signatures return an object instance return a null, such as the following:

...

  public Object getAttribute(String attribute) {
      return null;
  }

  public Enumeration getAttributeNames() {
      return null;
  }

  public String getRealPath(String path) {
      return null;
  }

...

In addition, the Request class still has the parse and the getUri methods, which were discussed in the previous article.

The Response Class

The Response class implements javax.servlet.ServletResponse. As such, the class must provide implementations for all of the methods in the interface. Similar to the Request class, I leave the implementations of all methods "blank," except the getWriter method.

public PrintWriter getWriter() {
    // autoflush is true, println() will flush,
    // but print() will not.
    writer = new PrintWriter(output, true);
    return writer;

}

The second argument to the PrintWriter class' constructor is a Boolean indicating whether or not autoflush is enabled. Passing true as the second argument will make any call to a println method flush the output. However, a print call does not flush the output. Therefore, if a call to a print method happens to be the last line in a servlet's service method, the output is not sent to the browser. This imperfection will be fixed in the later applications.

The Response class still has the sendStaticResource method discussed in the previous article.

The StaticResourceProcessor Class

The StaticResourceProcessor class is used to serve requests for static resources. Its only method is process, as shown in Listing 2.3.

Listing 2.3. The StaticResourceProcessor class' process method

public void process(Request request, Response response) {
    try {
        response.sendStaticResource();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

The process method receives two arguments: a Request instance and a Response instance. It simply calls the sendStaticResource method of the Response class.

Pages: 1, 2, 3, 4

Next Pagearrow