在 Java 11 及更高版本中使用 HttpClient 时如何跟踪 HTTP 303 状态代码?

Posted

技术标签:

【中文标题】在 Java 11 及更高版本中使用 HttpClient 时如何跟踪 HTTP 303 状态代码?【英文标题】:How to follow-through on HTTP 303 status code when using HttpClient in Java 11 and later? 【发布时间】:2021-05-25 06:35:39 【问题描述】:

在 Java 11 及更高版本中使用 java.net.http.HttpClient 类时,如何告诉客户端通过 HTTP 303 到达重定向页面?

这是一个例子。 Wikipedia provides a REST URL 用于获取其内容的随机页面的摘要。该 URL 重定向到随机选择的页面的 URL。运行此代码时,我在调用HttpResponse#toString 时看到303。但我不知道如何告诉客户端类跟随新的 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

身体 =

【问题讨论】:

【参考方案1】:

问题

您正在使用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 响应代码的响应,可以手动处理。

共有三个常量:ALWAYSNEVERNORMAL。前两个的意思从名字就很明显了。最后一个NORMAL 的行为与ALWAYS 类似,只是它不会从https URL 重定向到http URL。

手动跟随重定向

正如HttpClient.Redirect 的文档中所述,您可以改为手动跟随重定向。我不太熟悉 HTTP 以及如何正确处理所有响应,所以我不会在这里举个例子。但我相信,这至少需要您:

    检查响应的状态码。 如果代码指示重定向,请从 response headers 获取新 URI。 如果新 URI 是相对的,则根据请求 URI 解析它。 发送新请求。 根据需要重复 1-4。

显然,将HttpClient 配置为自动跟随重定向要容易得多(并且不易出错),但这种方法会给您更多的控制权。

【讨论】:

以上是关于在 Java 11 及更高版本中使用 HttpClient 时如何跟踪 HTTP 303 状态代码?的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Plus 中,当在 Oracle 11g 及更高版本中使用 lpad 时,第二列会获得额外的尾随空格

sh 在Mac 10.11.5及更高版本的10.11系列和10.12.1及更高版本的10.12系列中安装Caffe

AVKit.AVPlayerViewController - 控件在 iOS11 及更高版本中不可见

c++11 及更高版本中 mutex.lock() 和 .unlock() 的确切线程间重新排序约束是啥?

如何在 android 2.3 及更高版本中获取当前启动器的包名?

MD5:Java 7 及更高版本中 keytool.exe 的输出差异