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>
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 );
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
.