配置基于 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 Service 的 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.17.290</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 环境变量。