11.13. Handling Redirects

Problem

You need to access a server that may send an arbitrary number of redirects.

Solution

Before executing an HttpMethod call, setFollowRedirects(true) on the method; HttpClient will take care of following any redirects a server may return in a response. The following example shows what happens when a method requests a CGI script that returns a 302 (moved temporarily) response code:

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

HttpClient client = new HttpClient( );
String url = "http://www.discursive.com/cgi-bin/jccook/redirect.cgi";
    
System.out.println( "Executing Method not following redirects: ");        
HttpMethod method = new GetMethod( url );
method.setFollowRedirects( false );
executeMethod(client, method);

System.out.println( "Executing Method following redirects: ");        
method = new GetMethod( url );
method.setFollowRedirects( true );
executeMethod(client, method);

private 
               static 
               void executeMethod(HttpClient client, HttpMethod method)
    throws IOException, HttpException {
    client.executeMethod( method );
    System.out.println( "Response Code: " + method.getStatusCode( ) );
    String response = method.getResponseBodyAsString( );
    System.out.println( response );
    method.releaseConnection( );
    method.recycle( );
}

This example executes two GetMethod instances; the first method is configured not to follow redirects, and the second is configured to follow redirects. The first method is executed, and the server sends a 302 response code. Since this method is not configured to follow redirects, HttpClient does not make another request. When the second method is executed, HttpClient follows the initial redirect to a redirect2.cgi script, which sends another redirect to /jccook/index.html:

Executing Method not following redirects: 
0    INFO  [main] org.apache.commons.httpclient.HttpMethodBase     - Redirect 
requested but followRedirects is disabled
Response Code: 302

Executing Method following redirects: 
Response Code: 200
<html>
 <head>
  <title>JCCook Example</title>
 </head>
 <body>
  <h1>Hello World!</h1>
 </body>
</html>

Discussion

HttpClient can handle any of the following response codes specifying a redirect:

  • Status Code 302: HttpStatus.SC_MOVED_TEMPORARILY

  • Status Code 301: HttpStatus.SC_MOVED_PERMANENTLY

  • Status Code 303: HttpStatus.SC_SEE_OTHER

  • Status Code 307: HttpStatus.SC_TEMPORARY_REDIRECT

When a response code is retrieved, HttpClient sends another GET request for the resource specified in the Location header. The following code is the first request sent by a method configured to follow redirects:

GET /cgi-bin/jccook/redirect.cgi HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.0final
Host: www.discursive.com

The redirect.cgi script will then send a 302 Moved response, supplying a Location header that points to redirect2.cgi:

HTTP/1.1 302 Moved
Date: Sat, 15 May 2004 19:30:49 GMT
Server: Apache/2.0.48 (Fedora)
Location: /cgi-bin/jccook/redirect2.cgi
Content-Length: 0
Content-Type: text/plain; charset=UTF-8

HttpClient then sends another GET request for the resource specified in the previous response:

GET /cgi-bin/jccook/redirect2.cgi HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.0final
Host: www.discursive.com

The redirect2.cgi is configured to send a redirect for /jccook/index.html, and the response to the previous request does just that:

HTTP/1.1 302 Moved
Date: Sat, 15 May 2004 19:30:49 GMT
Server: Apache/2.0.48 (Fedora)
Location: /jccook/index.html
Content-Length: 0
Content-Type: text/plain; charset=UTF-8

How HttpClient handles redirect responses can be further customized by three configurable parameters on HttpClient. REJECT_RELATIVE_REDIRECT causes HttpClient to throw an exception if a server sends a Location header with a relative URL; for instance, if the redirect.cgi script returns a Location header of ../index.html, the redirection causes an exception if REJECT_RELATIVE_REDIRECT is set to true. If ALLOW_CIRCULAR_REDIRECTS is set to true, HttpClient throws an exception if a series of redirects includes the same resources more than once. MAX_REDIRECTS allows you to specify a maximum number of redirects to follow. The following example sets all three parameters on an instance of HttpClientParams associated with an instance of HttpClient:

HttpClient client = new HttpClient( );
HttpClientParams params = client.getParams( );

params.setBooleanParameter( HttpClientParams.REJECT_RELATIVE_REDIRECT, false );
params.setBooleanParameter( HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, false );
params.setIntParameter( HttpClientParams.MAX_REDIRECTS, 10 );

See Also

For more information on how HttpClient handles redirection, take a look at the source for the HttpMethodDirector. The isRedirectNeeded() and processRedirectResponse() methods handle redirection, and the source for this class can be viewed using ViewCVS (http://cvs.apache.org/viewcvs.cgi/jakarta-commons/httpclient/src/java/). Navigate to the org.apache.commons.httpclient package and click on HttpMethodDirector.

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

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