配置 URLConnection基于的 HTTP 客户端 - Amazon SDK for Java 2.x
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

配置 URLConnection基于的 HTTP 客户端

与默认客户端相比, Amazon SDK for Java 2.x 它提供了更轻量UrlConnectionHttpClient的 HTTP 客户端。ApacheHttpClientUrlConnectionHttpClient 基于 Java 的 URLConnection

UrlConnectionHttpClient 的加载速度比基于 Apache 的 HTTP 客户端快,但功能较少。由于加载速度更快,因此该客户端是 Java Amazon Lambda 函数的良好解决方案

UrlConnectionHttpClient 提供了几个可配置的选项供您使用。

注意

UrlConnectionHttpClient 不支持 HTTP PATCH 方法。

少数 Amazon API 操作需要补丁请求。这些操作的名称通常以 Update* 开头。以下是几个示例。

如果你可能使用UrlConnectionHttpClient,请先参阅你正在使用 Amazon Web Services 服务 的 API 参考。了解您需要的操作是否使用 PATCH 操作。

访问 UrlConnectionHttpClient

要配置和使用 UrlConnectionHttpClient,请在 pom.xml 文件中声明对 url-connection-client Maven 构件的依赖项。

ApacheHttpClient 不同的是,UrlConnectionHttpClient 不会自动添加到您的项目中,因此,要使用该客户端必须对其进行特别声明。

以下 pom.xml 文件示例显示了使用和配置 HTTP 客户端所需的依赖项。

<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.27.21</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- other dependencies such as s3 or dynamodb --> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>url-connection-client</artifactId> </dependency> </dependencies>

使用和配置 UrlConnectionHttpClient

您可以在生成服务客户端的同时配置一个 UrlConnectionHttpClient 实例,也可以将单个实例配置为在多个服务客户端之间共享。

无论采用哪种方法,都可以使用 UrlConnectionHttpClient.Builder 来配置 URLConnection基于的 HTTP 客户端的属性。

最佳实践:将一个 UrlConnectionHttpClient 实例专用于一个服务客户端

如果您需要配置 UrlConnectionHttpClient 实例,建议您生成专用 UrlConnectionHttpClient 实例。您可以通过使用服务客户端生成器的 httpClientBuilder 方法来执行此操作。这样,HTTP 客户端的生命周期就由 SDK 管理,这有助于避免在不再需要 UrlConnectionHttpClient 实例却不关闭实例时可能发生的内存泄漏。

以下示例创建了一个 S3Client 并配置了具有 socketTimeoutproxyConfiguration 值的 UrlConnectionHttpClient 嵌入式实例。proxyConfiguration 方法采用类型为 Consumer<ProxyConfiguration.Builder> 的 Java lambda 表达式。

导入

import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; import java.net.URI; import java.time.Duration;

代码

// Singleton: Use the s3Client for all requests. S3Client s3Client = S3Client.builder() .httpClientBuilder(UrlConnectionHttpClient.builder() .socketTimeout(Duration.ofMinutes(5)) .proxyConfiguration(proxy -> proxy.endpoint(URI.create("http://proxy.mydomain.net:8888")))) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .build(); // Perform work with the s3Client. s3Client.close(); // Requests completed: Close the s3client.

替代方法:共享 UrlConnectionHttpClient 实例

为了帮助降低应用程序的资源和内存使用量,您可以配置 UrlConnectionHttpClient 并在多个服务客户端之间共享该客户端。将共享 HTTP 连接池,从而降低资源使用量。

注意

共享 UrlConnectionHttpClient 实例时,必须在准备好弃置实例时将其关闭。服务客户端关闭后,SDK 不会关闭实例。

以下示例配置了由两个服务客户端使用的 URLConnection基于 HTTP 客户端。配置的 UrlConnectionHttpClient 实例将传递给每个生成器的 httpClient 方法。当不再需要服务客户端和 HTTP 客户端时,代码会显式关闭它们。代码最后关闭 HTTP 客户端。

导入

import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; import software.amazon.awssdk.awscore.defaultsmode.DefaultsMode; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.urlconnection.ProxyConfiguration; import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.s3.S3Client; import java.net.URI; import java.time.Duration;

代码

SdkHttpClient urlHttpClient = UrlConnectionHttpClient.create(); // Singletons: Use the s3Client and dynamoDbClient for all requests. S3Client s3Client = S3Client.builder() .httpClient(urlHttpClient) .defaultsMode(DefaultsMode.IN_REGION) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .build(); DynamoDbClient dynamoDbClient = DynamoDbClient.builder() .httpClient(urlHttpClient) .defaultsMode(DefaultsMode.IN_REGION) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .build(); // Perform work with the s3Client and dynamoDbClient. // Requests completed: Close all service clients. s3Client.close(); dynamoDbClient.close(); urlHttpClient.close();

在应用程序中使用 UrlConnectionHttpClient 时,您必须使用服务客户端生成器的 httpClientBuilder 方法为每个服务客户端提供一个 URLConnectionHttpClient 实例或一个 ApacheHttpClient 实例。

如果程序使用多个服务客户端,并且同时存在以下两个条件,则会发生异常:

  • 一个服务客户端配置为使用一个 UrlConnectionHttpClient 实例

  • 另一个服务客户端使用默认 ApacheHttpClient,但没有使用 httpClient()httpClientBuilder() 方法显式生成

该异常将声明在类路径中找到了多个 HTTP 实现。

以下示例代码片段会导致异常。

// The dynamoDbClient uses the UrlConnectionHttpClient DynamoDbClient dynamoDbClient = DynamoDbClient.builder() .httpClient(UrlConnectionHttpClient.create()) .build(); // The s3Client below uses the ApacheHttpClient at runtime, without specifying it. // An SdkClientException is thrown with the message that multiple HTTP implementations were found on the classpath. S3Client s3Client = S3Client.create(); // Perform work with the s3Client and dynamoDbClient. dynamoDbClient.close(); s3Client.close();

通过显式使用 ApacheHttpClient 来配置 S3Client,可避免异常。

DynamoDbClient dynamoDbClient = DynamoDbClient.builder() .httpClient(UrlConnectionHttpClient.create()) .build(); S3Client s3Client = S3Client.builder() .httpClient(ApacheHttpClient.create()) // Explicitly build the ApacheHttpClient. .build(); // Perform work with the s3Client and dynamoDbClient. dynamoDbClient.close(); s3Client.close();
注意

要显式创建 ApacheHttpClient,必须在 Maven 项目文件中添加对 apache-client 构件的依赖项

代理配置示例

以下代码片段将代理配置生成器用于 URL 连接 HTTP 客户端

SdkHttpClient urlHttpClient = UrlConnectionHttpClient.builder() .proxyConfiguration(ProxyConfiguration.builder() .endpoint(URI.create("http://example.com:1234")) .username("username") .password("password") .addNonProxyHost("localhost") .addNonProxyHost("host.example.com") .build()) .build();

以下命令行片段显示了代理配置的等效 Java 系统属性。

$ java -Dhttp.proxyHost=example.com -Dhttp.proxyPort=1234 -Dhttp.proxyUser=username \ -Dhttp.proxyPassword=password -Dhttp.nonProxyHosts=localhost|host.example.com -cp ... App

使用环境变量的等效设置为:

// Set the following environment variables. // $ export HTTP_PROXY="http://username:password@example.com:1234" // $ export NO_PROXY="localhost|host.example.com" // Set the 'useSystemPropertyValues' to false on the proxy configuration. SdkHttpClient apacheHttpClient = UrlConnectionHttpClient.builder() .proxyConfiguration(ProxyConfiguration.builder() .useSystemPropertyValues(Boolean.FALSE) .build()) .build(); // Run the application. // $ java -cp ... App
注意

URLConnection基于的 HTTP 客户端当前不支持 HTTPS 代理系统属性或 HTTPS_PROXY 环境变量。