Module java.net.http
Package java.net.http

Class HttpClient

java.lang.Object
java.net.http.HttpClient
所有已实现的接口:
AutoCloseable

public abstract class HttpClient extends Object implements AutoCloseable
一个HTTP客户端。

HttpClient可以用于发送请求并检索它们的响应。通过builder创建HttpClientnewBuilder方法返回一个创建默认HttpClient实例的构建器。构建器可用于配置每个客户端状态,如:首选协议版本(HTTP/1.1或HTTP/2)、是否跟随重定向、代理、认证器等。构建完成后,HttpClient是不可变的,并可用于发送多个请求。

HttpClient为通过它发送的所有请求提供配置信息和资源共享。 HttpClient实例通常管理自己的连接池,可以在必要时重用这些连接。连接池通常不在HttpClient实例之间共享。为每个操作创建一个新客户端虽然可能,但通常会阻止重用这些连接。

每个发送的HttpRequest必须提供一个BodyHandlerBodyHandler确定如何处理响应主体(如果有)。一旦接收到HttpResponse,则可获取标头、响应代码和主体(通常)。是否已读取响应主体字节取决于响应主体的类型T

请求可以同步或异步发送:

同步示例

HttpClient client = HttpClient.newBuilder()
     .version(Version.HTTP_1_1)
     .followRedirects(Redirect.NORMAL)
     .connectTimeout(Duration.ofSeconds(20))
     .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
     .authenticator(Authenticator.getDefault())
     .build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());

异步示例

 HttpRequest request = HttpRequest.newBuilder()
     .uri(URI.create("https://foo.com/"))
     .timeout(Duration.ofMinutes(2))
     .header("Content-Type", "application/json")
     .POST(BodyPublishers.ofFile(Paths.get("file.json")))
     .build();
client.sendAsync(request, BodyHandlers.ofString())
     .thenApply(HttpResponse::body)
     .thenAccept(System.out::println);

安全检查

如果存在安全管理器,则HTTP客户端的发送方法将执行安全检查。访问目标服务器和代理服务器(如果已配置)需要适当的URLPermission。访问代理所需的URLPermission形式具有method参数为"CONNECT"(适用于所有类型的代理)和URL字符串形式为"socket://host:port",其中主机和端口指定代理的地址。

API 注意:
HttpClient分配的资源可以通过关闭客户端来提前回收。
实现注意:

JDK内置的HttpClient实现覆盖了close()shutdown()shutdownNow()awaitTermination(Duration)isTerminated(),提供了最佳实现。未关闭、取消或读取返回的流直到耗尽,例如使用HttpResponse.BodyHandlers.ofInputStream()HttpResponse.BodyHandlers.ofLines()HttpResponse.BodyHandlers.ofPublisher()时提供的流,可能会阻止在shutdown()之前提交的请求完成运行。同样,未请求数据取消订阅来自自定义BodySubscriber的操作可能会停止数据传递并阻止有序关闭

如果未为HttpClient设置显式executor,并且已安装安全管理器,则默认执行程序将在未授予任何权限的上下文中执行异步和依赖任务。如果执行需要权限的操作,自定义请求主体发布者响应主体处理程序响应主体订阅者WebSocket监听器应在适当的特权上下文中执行。

自 JDK 版本:
11
  • Constructor Details

    • HttpClient

      protected HttpClient()
      创建一个HttpClient。
  • Method Details

    • newHttpClient

      public static HttpClient newHttpClient()
      返回具有默认设置的新HttpClient

      等同于newBuilder().build()

      默认设置包括:"GET"请求方法、首选HTTP/2、重定向策略为NEVER默认代理选择器默认SSL上下文

      实现注意事项:
      系统范围内的默认值是在构造HttpClient实例时检索的。在构建了HttpClient实例之后更改系统范围内的值,例如通过调用ProxySelector.setDefault(ProxySelector)SSLContext.setDefault(SSLContext),对已构建的实例没有影响。
      返回:
      一个新的HttpClient
      抛出:
      UncheckedIOException - 如果必要的底层IO资源无法分配以构建新的HttpClient
    • newBuilder

      public static HttpClient.Builder newBuilder()
      创建一个新的HttpClient构建器。

      此方法返回的构建器创建默认HttpClient实现的实例。

      返回:
      一个HttpClient.Builder
    • cookieHandler

      public abstract Optional<CookieHandler> cookieHandler()
      返回一个包含此客户端的CookieHandlerOptional。如果在此客户端的构建器中未设置CookieHandler,则Optional为空。
      返回:
      一个包含此客户端的CookieHandlerOptional
    • connectTimeout

      public abstract Optional<Duration> connectTimeout()
      返回一个包含此客户端的连接超时持续时间Optional。如果在客户端的构建器中未设置连接超时持续时间,则Optional为空。
      返回:
      一个包含此客户端的连接超时持续时间的Optional
    • followRedirects

      public abstract HttpClient.Redirect followRedirects()
      返回此客户端的重定向策略。对于未指定重定向策略的构建的客户端,默认值为NEVER
      返回:
      此客户端的重定向设置
    • proxy

      public abstract Optional<ProxySelector> proxy()
      返回一个包含提供给此客户端的ProxySelectorOptional。如果在此客户端的构建器中未设置代理选择器,则Optional为空。

      尽管此方法可能返回一个空的可选项,HttpClient仍可能具有一个未公开的默认代理选择器,用于发送HTTP请求。

      返回:
      一个包含提供给此客户端的代理选择器的Optional
    • sslContext

      public abstract SSLContext sslContext()
      返回此客户端的SSLContext

      如果在此客户端的构建器中未设置SSLContext,则返回默认上下文

      返回:
      此客户端的SSLContext
    • sslParameters

      public abstract SSLParameters sslParameters()
      返回此客户端的SSLParameters的副本。

      如果在客户端的构建器中未设置SSLParameters,则返回客户端将使用的特定默认参数集。

      返回:
      此客户端的SSLParameters
    • authenticator

      public abstract Optional<Authenticator> authenticator()
      返回一个包含在此客户端上设置的AuthenticatorOptional。如果在客户端的构建器中未设置Authenticator,则Optional为空。
      返回:
      一个包含此客户端的AuthenticatorOptional
    • version

      public abstract HttpClient.Version version()
      返回此客户端的首选HTTP协议版本。默认值为HttpClient.Version.HTTP_2
      实现注意事项:
      约束也可能影响协议版本的选择。例如,如果通过代理请求HTTP/2,并且实现不支持此模式,则可能使用HTTP/1.1
      返回:
      请求的HTTP协议版本
    • executor

      public abstract Optional<Executor> executor()
      返回一个包含此客户端的ExecutorOptional。如果在客户端的构建器中未设置Executor,则Optional为空。

      尽管此方法可能返回一个空的可选项,HttpClient仍可能具有一个未公开的默认执行器,用于执行异步和依赖任务。

      返回:
      一个包含此客户端的ExecutorOptional
    • send

      public abstract <T> HttpResponse<T> send(HttpRequest request, HttpResponse.BodyHandler<T> responseBodyHandler) throws IOException, InterruptedException
      使用此客户端发送给定请求,必要时阻塞以获取响应。返回的HttpResponse<T>包含响应状态、标头和正文(由给定的响应正文处理程序处理)。

      如果操作被中断,默认的HttpClient实现会尝试取消HTTP交换,并抛出InterruptedException。不能保证取消请求何时会被考虑。特别是,请求可能仍然被发送到服务器,因为其处理可能已经在另一个线程中异步开始,并且底层资源可能仅以异步方式释放。

      • 对于HTTP/1.1,尝试取消可能导致底层连接突然关闭。
      • 对于HTTP/2,在某些情况下,尝试取消可能导致流被重置,或者也可能导致连接突然关闭,例如,如果线程当前正在尝试写入底层套接字。
      类型参数:
      T - 响应正文类型
      参数:
      request - 请求
      responseBodyHandler - 响应正文处理程序
      返回:
      响应
      抛出:
      IOException - 发送或接收时发生I/O错误,或客户端已关闭
      InterruptedException - 如果操作被中断
      IllegalArgumentException - 如果request参数不是可以根据HttpRequest.Builder指定的方式有效构建的请求。
      SecurityException - 如果已安装安全管理器并且拒绝给定请求中的URL或代理(如果已配置)的访问。有关更多信息,请参见安全检查
    • sendAsync

      public abstract <T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request, HttpResponse.BodyHandler<T> responseBodyHandler)
      使用此客户端异步发送给定请求,并使用给定的响应正文处理程序。

      等效于:sendAsync(request, responseBodyHandler, null)

      类型参数:
      T - 响应正文类型
      参数:
      request - 请求
      responseBodyHandler - 响应正文处理程序
      返回:
      一个CompletableFuture<HttpResponse<T>>
      抛出:
      IllegalArgumentException - 如果request参数不是可以根据HttpRequest.Builder指定的方式有效构建的请求。
    • sendAsync

      public abstract <T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request, HttpResponse.BodyHandler<T> responseBodyHandler, HttpResponse.PushPromiseHandler<T> pushPromiseHandler)
      发送给定请求,使用此客户端异步处理,并使用给定的响应主体处理程序和推送承诺处理程序。

      如果成功完成,返回的CompletableFuture将完成,其中包含响应状态、标头和主体(由给定的响应主体处理程序处理)。

      接收到的推送承诺(如果有)将由给定的pushPromiseHandler处理。值为null的pushPromiseHandler将拒绝任何推送承诺。

      返回的CompletableFuture异常完成:

      • IOException - 如果在发送或接收时发生I/O错误,或客户端已关闭。
      • SecurityException - 如果已安装安全管理器并且拒绝对给定请求中的URL或代理(如果已配置)的访问。有关更多信息,请参见安全检查。

      默认的HttpClient实现返回可取消的CompletableFuture对象。从可取消的futures派生的CompletableFuture对象本身是可取消的。在未完成的可取消future上调用cancel(true)会尝试取消HTTP交换以尽快释放底层资源。不能保证取消请求何时会被考虑。特别是,请求可能仍然会被发送到服务器,因为其处理可能已经在另一个线程中异步开始,并且底层资源可能仅以异步方式释放。

      • 对于HTTP/1.1,尝试取消可能导致底层连接突然关闭。
      • 对于HTTP/2,尝试取消可能导致流被重置。
      类型参数:
      T - 响应主体类型
      参数:
      request - 请求
      responseBodyHandler - 响应主体处理程序
      pushPromiseHandler - 推送承诺处理程序,可以为null
      返回:
      CompletableFuture<HttpResponse<T>>
      抛出:
      IllegalArgumentException - 如果request参数不是按照HttpRequest.Builder指定的方式构建的有效请求。
    • newWebSocketBuilder

      public WebSocket.Builder newWebSocketBuilder()
      创建一个新的WebSocket构建器(可选操作)。

      示例

      HttpClient client = HttpClient.newHttpClient();
      CompletableFuture<WebSocket> ws = client.newWebSocketBuilder()
         .buildAsync(URI.create("ws://websocket.example.com"), listener);

      通过使用自定义HttpClient可以实现对WebSocket开启握手的更精细控制。

      示例

      InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80);
      HttpClient client = HttpClient.newBuilder()
              .proxy(ProxySelector.of(addr))
              .build();
      
      CompletableFuture<WebSocket> ws = client.newWebSocketBuilder()
              .buildAsync(URI.create("ws://websocket.example.com"), listener);
      实现要求:
      此方法的默认实现会抛出UnsupportedOperationException。通过newHttpClient()或newBuilder()获取的客户端将返回一个WebSocket构建器。
      实现说明:
      该构建器及其创建的WebSocket均以非阻塞方式运行。也就是说,它们的方法在返回CompletableFuture之前不会阻塞。异步任务在此HttpClient的执行器中执行。

      当从Listener.onClose返回的CompletionStage完成时,WebSocket将发送一个具有与接收消息相同代码和空原因的Close消息。

      返回:
      WebSocket.Builder
      抛出:
      UnsupportedOperationException - 如果此HttpClient不提供WebSocket支持
    • shutdown

      public void shutdown()
      启动有序关闭,先前使用send或sendAsync提交的请求将运行到完成,但不会接受新请求。运行请求到完成可能涉及在后台运行多个操作,包括等待响应被传递,所有这些操作都必须运行到完成,直到请求被视为完成。如果已经关闭,则调用不会产生额外效果。

      此方法不会等待先前提交的请求完成执行。使用awaitTermination或close来完成。

      实现要求:
      此方法的默认实现不执行任何操作。子类应重写此方法以实现适当的行为。
      自:
      21
      参见:
    • awaitTermination

      public boolean awaitTermination(Duration duration) throws InterruptedException
      在关闭请求后,或经过持续时间,或当前线程被中断之前,阻塞直到所有操作完成执行。操作是指运行先前使用send或sendAsync提交的请求所需的任何任务,直到完成。

      如果等待时间小于或等于零,则此方法不会等待。在这种情况下,该方法只是测试线程是否已终止。

      实现要求:
      此方法的默认实现检查空参数,但否则不执行任何操作并返回true。子类应重写此方法以实现适当的行为。
      参数:
      duration - 等待的最长时间
      返回:
      如果此客户端终止,则为true,如果超时在终止之前到期,则为false
      抛出:
      InterruptedException - 在等待时被中断
      自:
      21
      参见:
    • isTerminated

      public boolean isTerminated()
      在关闭后,如果所有操作都已完成,则返回true。操作是指运行先前使用send或sendAsync提交的请求所需的任何任务。

      请注意,除非首先调用shutdown或shutdownNow,否则isTerminated永远不会为true。

      实现要求:
      此方法的默认实现不执行任何操作并返回false。子类应重写此方法以实现适当的行为。
      返回:
      如果所有任务在关闭后已完成,则为true
      自:
      21
      参见:
    • shutdownNow

      public void shutdownNow()
      此方法尝试启动立即关闭。此方法的实现可能会尝试中断正在运行的操作。操作是指运行先前使用send或sendAsync提交的请求所需的任何任务。当中断时正在运行的操作的行为是未定义的。特别地,不能保证中断的操作将终止,或者等待这些操作的代码将被通知。
      实现要求:
      此方法的默认实现只是调用shutdown。子类应重写此方法以实现适当的行为。
      自:
      21
      参见:
    • close

      public void close()
      启动有序关闭,先前提交给send或sendAsync的请求将运行到完成,但不会接受新请求。运行请求到完成可能涉及在后台运行多个操作,包括等待响应被传递。此方法将等待直到所有操作完成执行并且客户端已终止。

      在等待时如果被中断,此方法可能会尝试通过调用shutdownNow来停止所有操作。然后继续等待,直到所有正在执行的操作完成。在此方法返回之前,中断状态将被重新断言。

      如果已经终止,则调用此方法不会产生任何效果。

      指定者:
      close 在接口 AutoCloseable
      实现要求:
      默认实现调用shutdown()并等待任务完成执行,使用awaitTermination
      自:
      21
      参见: