在Java11及更高版本中使用HttpClient时如何跟进HTTP303状态代码?
在使用java.net.http.HttpClientJava 11 及更高版本中的类时,如何告诉客户端遵循HTTP 303以到达重定向页面?
这是一个例子。维基百科提供了一个 REST URL,用于获取其内容的随机页面的摘要。该 URL 重定向到随机选择的页面的 URL。运行此代码时,我看到303调用HttpResponse#toString. 但我不知道如何告诉客户端类跟随新的 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();
}
运行时:
响应 = (GET https://en.wikipedia.org/api/rest_v1/page/random/summary ) 303
身体 =
回答
问题
您正在使用HttpClient#newHttpClient(). 该方法的文档指出:
返回一个新
HttpClient的默认设置。相当于
newBuilder().build()。默认设置包括:“GET”请求方法、HTTP/2 首选项、
NEVER[强调添加]重定向策略、默认代理选择器和默认 SSL 上下文。
如前所述,您正在创建HttpClient一个重定向策略为NEVER.
解决方案
您的问题至少有两种解决方案。
自动跟随重定向
如果您想自动跟随重定向,那么您需要使用HttpClient#newBuilder()(而不是#newHttpClient())它允许您配置要构建的客户端。具体来说,您需要HttpClient.Builder#followRedirects(HttpClient.Redirect)在构建客户端之前使用适当的重定向策略进行调用。例如:
HttpClient client =
HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.NORMAL) // follow redirects
.build();
不同的重定向策略由HttpClient.Redirect枚举指定:
定义自动重定向策略。
每当
3XX收到响应代码时,都会检查自动重定向策略。如果重定向没有自动发生3XX,则返回包含响应代码的响应,可以手动处理。
有三个常量:ALWAYS,NEVER,和NORMAL。前两者的含义从它们的名字就很明显了。最后一个 , 的NORMAL行为就像是ALWAYS它不会从httpsURL重定向到httpURL。
手动跟踪重定向
如文档中所述,HttpClient.Redirect您可以改为手动跟踪重定向。我不精通 HTTP 以及如何正确处理所有响应,所以我不会在这里举例。但我相信,至少,这需要你:
- 检查响应的状态代码。
- 如果代码指示重定向,请从响应标头中获取新 URI 。
- 如果新 URI 是相对的,则根据请求 URI 解析它。
- 发送新请求。
- 根据需要重复 1-4。
显然,将 配置HttpClient为自动跟随重定向要容易得多(并且不易出错),但是这种方法会给您更多的控制权。