11.5. Retrieving Content with a Conditional GET

Problem

You need to retrieve the same content more than once, and you would like to have the server only send the content if it has changed since the last request.

Solution

Create a GetMethod and set the If-None-Match and If-Modified-Since headers; these two headers will instruct the server to refrain from sending content if the content has not been altered since the last request. Example 11-1 makes three separate requests for the same URL (http://www.apache.org), and, because the content remains static, it is only sent in the response body of the first request.

Example 11-1. Requesting information with a conditional GET

                  import java.io.IOException;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HeaderElement;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;

public 
                  class ConditionalGetExample {

    public 
                  static 
                  void main(String[] args) throws HttpException, IOException {
        ConditionalGetExample example = new ConditionalGetExample( );
        example.start( );
    }
    
    String entityTag = "";
    String lastModified = "";
    
    public 
                  void start( ) throws HttpException, IOException {

        HttpClient client = new HttpClient( );
        HttpMethod method = new GetMethod("http://www.apache.org");

        for( int i = 0; i < 3; i++ ) {
            setHeaders(method);
            client.executeMethod(method);
            processResults(method);
            method.releaseConnection( );
            method.recycle( );
        }
    }

    private 
                  void setHeaders(HttpMethod method) {
        method.setRequestHeader(new Header("If-None-Match", entityTag ) );
        method.setRequestHeader(new Header("If-Modified-Since", 
                               lastModified ) );
    }

    private 
                  void processResults(HttpMethod method) throws HttpException {
        if(method.getStatusCode( ) == HttpStatus.SC_NOT_MODIFIED ) {
            System.out.println( "Content not modified since last request" );
        } else {
            entityTag = retrieveHeader( method, "ETag" );
            lastModified = retrieveHeader( method, "Last-Modified" );
            System.out.println( "Get Method retrieved content." );
            System.out.println( "Entity Tag: " + entityTag );
            System.out.println( "Last Modified: " + lastModified );
        } 
    }
    
    private String retrieveHeader( HttpMethod method, String name ) 
        throws HttpException {
        HeaderElement[] header = method.getResponseHeader("ETag").
                                 getElements( );
        String value = "";
        if(header.length > 0) {
         value = header[0].getName( );
        }
        return value;
    }
}

Example 11-1 requests the same page three times; the first request retrieves the content, and the second and third requests contain the headers for a conditional HTTP GET. Because the Apache homepage remains unchanged throughout this example, the content of http://www.apache.org is retrieved only once. This example uses the headers in the first response to populate the If-None-Match and If-Modified-Since headers for the second and third requests:

Request 1. Get Method retrieved content.
Entity Tag: "2da794a-2d0d-998ebc80"
Last Modified: Wed, 14 Apr 2004 05:53:38 GMT

Request 2. Content not modified since last request

Request 3. Content not modified since last request

Discussion

This first request is similar to a regular HTTP GET, and if you examine the contents of the first request and response, you will see that the server’s response contains two headers:

Last-Modified: Wed, 05 May 2004 02:51:59 GMT
ETag: "a06d2-76-829811c0"

Example 11-1 takes the values of these two response headers and stores them in the entityTag and lastModified variables. When the next request is made, the values of these two variables are used to populate the conditional headers If-None-Match and If-Modified-Since in the setHeaders() method. These request headers are present in the second request for the same resource:

GET / HTTP/1.1
If-None-Match: "2da7807-31a8-e1eeb400"
If-Modified-Since: Tue, 11 May 2004 23:57:04 GMT
User-Agent: Jakarta Commons-HttpClient/3.0final
Host: www.apache.org

When the server receives these conditional headers, it will check to see if the resource has been modified. If the resource has been modified, the resource will have a different modified date and different entity tag value. If the resource has not been modified, the server will respond to HttpClient with a 304 Not Modified response code:

HTTP/1.1 304 Not Modified
Date: Sat, 15 May 2004 16:59:23 GMT
Server: Apache/2.0.49-dev (Unix)
ETag: "2da7807-31a8-e1eeb400"
Expires: Sun, 16 May 2004 16:59:23 GMT
Cache-Control: max-age=86400

The ETag header is known as an entity tag, and it is similar to a hash code for a resource served by a particular web server. Different servers have different algorithms for creating an ETag header; for example, the Apache HTTPD server has a configuration directive, which allows you to base an ETag on a configurable set of file attributes, such as size, i-node number, and modified time. Consider an ETag to be a unique identifier for a particular version of a resource; if this header changes, the corresponding resource has been altered.

See Also

Entity tags (the ETag header) are described in sections 3.11 and 14.19 of RFC 2616 (http://www.zvon.org/tmRFC/RFC2616/Output/index.html). The Apache HTTPD server can be configured to use different file attributes when creating an ETag header. For more information about configuring the Apache HTTPD server via the FileETag directive, see the documentation of Apache’s core features (http://httpd.apache.org/docs-2.0/mod/core.html#fileetag).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.35.255