When using the java.net.http.HttpClient
classes in Java 11 and later, how does one tell the client to follow through an HTTP 303 to get to the redirected page?
Here is an example. Wikipedia provides a REST URL for getting the summary of a random page of their content. That URL redirects to the URL of the randomly-chosen page. When running this code, I see the 303
when calling HttpResponse#toString
. But I do not know how to tell the client class to follow along to the new URL.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request =
HttpRequest
.newBuilder()
.uri( URI.create( "https://en.wikipedia.org/api/rest_v1/page/random/summary" ) )
.build();
try
{
HttpResponse < String > response = client.send( request , HttpResponse.BodyHandlers.ofString() );
System.out.println( "response = " + response ); // ⬅️ We can see the `303` status code.
String body = response.body();
System.out.println( "body = " + body );
}
catch ( IOException e )
{
e.printStackTrace();
}
catch ( InterruptedException e )
{
e.printStackTrace();
}
When run:
response = (GET https://en.wikipedia.org/api/rest_v1/page/random/summary) 303
body =
You're using HttpClient#newHttpClient()
. The documentation of that method states:
Returns a new
HttpClient
with default settings.Equivalent to
newBuilder().build()
.The default settings include: the "GET" request method, a preference of HTTP/2, a redirection policy of
NEVER
[emphasis added], the default proxy selector, and the default SSL context.
As emphasized, you are creating an HttpClient
with a redirection policy of NEVER
.
There are at least two solutions to your problem.
If you want to automatically follow redirects then you need to use HttpClient#newBuilder()
(instead of #newHttpClient()
) which allows you to configure the to-be-built client. Specifically, you need to call HttpClient.Builder#followRedirects(HttpClient.Redirect)
with an appropriate redirect policy before building the client. For example:
HttpClient client =
HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.NORMAL) // follow redirects
.build();
The different redirect policies are specified by the HttpClient.Redirect
enum:
Defines the automatic redirection policy.
The automatic redirection policy is checked whenever a
3XX
response code is received. If redirection does not happen automatically, then the response, containing the3XX
response code, is returned, where it can be handled manually.
There are three constants: ALWAYS
, NEVER
, and NORMAL
. The meaning of the first two is obvious from their names. The last one, NORMAL
, behaves just like ALWAYS
except it won't redirect from https
URLs to http
URLs.
As noted in the documentation of HttpClient.Redirect
you could instead manually follow a redirect. I'm not well versed in HTTP and how to properly handle all responses so I won't give an example here. But I believe, at a minimum, this requires you:
Obviously configuring the HttpClient
to automatically follow redirects is much easier (and less error-prone), but this approach would give you more control.