home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Book Home Java Servlet Programming Search this book

5.6. HTTP Headers

A servlet can set HTTP headers to provide extra information about its response. As we said in Chapter 4, "Retrieving Information", a full discussion of all the possible HTTP 1.0 and HTTP 1.1 headers is beyond the scope of this book. Table 5-2 lists the HTTP headers that are most often set by servlets as a part of a response.

Table 5-2. HTTP Response Headers

Header

Usage

Cache-Control

Specifies any special treatment a caching system should give to this document. The most common values are no-cache (to indicate this document should not be cached), no-store (to indicate this document should not be cached or even stored by a proxy server, usually due to its sensitive contents), and max-age=seconds (to indicate how long before the document should be considered stale). This header was introduced in HTTP 1.1.

Pragma

The HTTP 1.0 equivalent of Cache-control, with no-cache as its only possible value.

Connection

Used to indicate whether the server is willing to maintain an open (persistent) connection to the client. If so, its value is set to keep-alive. If not, its value is set to close. Most web servers handle this header on behalf of their servlets, automatically setting its value to keep-alive when a servlet sets its Content-Length header.

Retry-After

Specifies a time when the server can again handle requests, used with the SC_SERVICE_UNAVAILABLE status code. Its value is either an int that represents the number of seconds or a date string that represents an actual time.

Expires

Specifies a time when the document may change or when its information will become invalid. It implies that it is unlikely the document will change before that time.

Location

Specifies a new location of a document, usually used with the status codes SC_CREATED, SC_MOVED_PERMANENTLY, and SC_MOVED_TEMPORARILY. Its value must be a fully qualified URL (including "http://").

WWW-Authenticate

Specifies the authorization scheme and the realm of authorization required by the client to access the requested URL. Used with the status code SC_UNAUTHORIZED.

Content-Encoding

Specifies the scheme used to encode the response body. Possible values are gzip (or x-gzip) and compress (or x-compress). Multiple encodings should be represented as a comma-separated list in the order in which the encodings were applied to the data.

5.6.1. Setting an HTTP Header

The HttpServletResponse class provides a number of methods to assist servlets in setting HTTP response headers. Use setHeader() to set the value of a header:

public void HttpServletResponse.setHeader(String name, String value)

This method sets the value of the named header as a String. The name is case insensitive, as it is for all these methods. If the header had already been set, the new value overwrites the previous one. Headers of all types can be set with this method.

If you need to specify a time stamp for a header, you can use setDateHeader() :

public void HttpServletResponse.setDateHeader(String name, long date)

This method sets the value of the named header to a particular date and time. The method accepts the date value as a long that represents the number of milliseconds since the epoch (midnight, January 1, 1970 GMT). If the header has already been set, the new value overwrites the previous one.

Finally, you can use setIntHeader() to specify an integer value for a header:

public void HttpServletResponse.setIntHeader(String name, int value)

This method sets the value of the named header as an int. If the header had already been set, the new value overwrites the previous one.

The containsHeader() method provides a way to check if a header already exists:

public boolean HttpServletResponse.containsHeader(String name)

This method returns true if the named header has already been set, false if not.

In addition, the HTML 3.2 specification defines an alternate way to set header values using the <META HTTP-EQUIV> tag inside the HTML page itself:

<META HTTP-EQUIV="name" CONTENT="value">

This tag must be sent as part of the <HEAD> section of the HTML page. This technique does not provide any special benefit to servlets; it was developed for use with static documents, which do not have access to their own headers.

5.6.2. Redirecting a Request

One of the useful things a servlet can do using status codes and headers is redirect a request. This is done by sending instructions for the client to use another URL in the response. Redirection is generally used when a document moves (to send the client to the new location), for load balancing (so one URL can distribute the load to several different machines), or for simple randomization (choosing a destination at random).

Example 5-7 shows a servlet that performs a random redirect, sending a client to a random site selected from its site list. Depending on the site list, a servlet like this could have many uses. As it stands now, it's just a jump-off point to a selection of cool servlet sites. With a site list containing advertising images, it can be used to select the next ad banner.

Example 5-7. Random redirector

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SiteSelector extends HttpServlet {

  Vector sites = new Vector();
  Random random = new Random();

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    sites.addElement("http://www.oreilly.com/catalog/jservlet");
    sites.addElement("http://www.servlets.com");
    sites.addElement("http://jserv.java.sun.com");
    sites.addElement("http://www.servletcentral.com");
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    int siteIndex = Math.abs(random.nextInt()) % sites.size();
    String site = (String)sites.elementAt(siteIndex);

    res.setStatus(res.SC_MOVED_TEMPORARILY);
    res.setHeader("Location", site);
  }
}

The actual redirection happens in two lines:

res.setStatus(res.SC_MOVED_TEMPORARILY);
res.setHeader("Location", site);

The first line sets the status code to indicate a redirection is to take place, while the second line gives the new location. To guarantee they will work, you must call these methods before you send any output. Remember, the HTTP protocol sends status codes and headers before the content body. Also, the new site must be given as an absolute URL (for example, http://server:port/path/file.html). Anything less than that may confuse the client.

These two lines can be simplified to one using the sendRedirect() convenience method:

public void HttpServletResponse.sendRedirect(String location) throws IOException

This method redirects the response to the specified location, automatically setting the status code and Location header. For our example, the two lines become simply:

res.sendRedirect(site);

5.6.3. Client Pull

Client pull is similar to redirection, with one major difference: the browser actually displays the content from the first page and waits some specified amount of time before retrieving and displaying the content from the next page. It's called client pull because the client is responsible for pulling the content from the next page.

Why is this useful? For two reasons. First, the content from the first page can explain to the client that the requested page has moved before the next page is automatically loaded. Second, pages can be retrieved in sequence, making it possible to present a slow-motion page animation.

Client pull information is sent to the client using the Refresh HTTP header. This header's value specifies the number of seconds to display the page before pulling the next one, and it optionally includes a URL string that specifies the URL from which to pull. If no URL is given, the same URL is used. Here's a call to setHeader() that tells the client to reload this same servlet after showing its current content for three seconds:

setHeader("Refresh", "3");

And here's a call that tells the client to display Netscape's home page after the three seconds:

setHeader("Refresh", "3; URL=http://home.netscape.com");

Example 5-8 shows a servlet that uses client pull to display the current time, updated every 10 seconds.

Example 5-8. The current time, kept current

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ClientPull extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    res.setHeader("Refresh", "10");
    out.println(new Date().toString());
  }
}

This is an example of a text-based animation--we'll look at graphical animations in the next chapter. Note that the Refresh header is nonrepeating. It is not a directive to load the document repeatedly. For this example, however, the Refresh header is specified on each retrieval, creating a continuous display.

The use of client pull to retrieve a second document is shown in Example 5-9. This servlet redirects requests for one host to another host, giving an explanation to the client before the redirection.

Example 5-9. An explained host change

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ClientPullMove extends HttpServlet {

  static final String NEW_HOST = "http://www.oreilly.com";

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    String newLocation = NEW_HOST + req.getRequestURI();

    res.setHeader("Refresh", "10; URL=" + newLocation);

    out.println("The requested URI has been moved to a different host.<BR>");
    out.println("Its new location is " + newLocation + "<BR>");
    out.println("Your browser will take you there in 10 seconds.");
  }
}

This servlet generates the new location from the requested URI, which allows it to redirect any requests made to the old server. With the Java Web Server, this servlet could be configured to handle every request, to gradually transition clients to the new location.



Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.