

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

# 配置 URLConnection基于的 HTTP 客户端
<a name="http-configuration-url"></a>

与默认客户端相比， AWS SDK for Java 2.x 它提供了更轻量`[UrlConnectionHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html)`的 HTTP 客户端。`ApacheHttpClient``UrlConnectionHttpClient` 基于 Java 的 `[URLConnection](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/URLConnection.html)`。

`UrlConnectionHttpClient` 的加载速度比基于 Apache 的 HTTP 客户端快，但功能较少。由于加载速度更快，因此该客户端是 Java AWS Lambda 函数的[良好解决方案](lambda-optimize-starttime.md)。

`UrlConnectionHttpClient` 提供了几个[可配置的选项](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.Builder.html)供您使用。

**注意**  
`UrlConnectionHttpClient` 不支持 HTTP PATCH 方法。  
少数 AWS API 操作需要补丁请求。这些操作的名称通常以 `Update*` 开头。以下是几个示例。  
 AWS Security Hub CSPM API 中的@@ [几个`Update*`操作](https://docs.aws.amazon.com/securityhub/1.0/APIReference/API_Operations.html)以及[BatchUpdateFindings](https://docs.aws.amazon.com/securityhub/1.0/APIReference/API_BatchUpdateFindings.html)操作
所有 Amazon API Gateway API 的 [`Update*` 操作](https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateAccount.html)
如果你可能使用`UrlConnectionHttpClient`，请先参阅你正在使用 AWS 服务 的 API 参考。了解您需要的操作是否使用 PATCH 操作。

## 访问 `UrlConnectionHttpClient`
<a name="http-url-dependency"></a>

要配置和使用 `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`
<a name="http-url-config"></a>

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

无论采用哪种方法，您都可以使用 [UrlConnectionHttpClient.Builder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.Builder.html) 来配置 URLConnection基于的 HTTP 客户端的属性。

### 最佳实践：将一个 `UrlConnectionHttpClient` 实例专用于一个服务客户端
<a name="http-config-url-one-client"></a>

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

以下示例创建了一个 `S3Client` 并配置了具有 `socketTimeout` 和 `proxyConfiguration` 值的 `UrlConnectionHttpClient` 嵌入式实例。`proxyConfiguration` 方法采用类型为 ` Consumer<[ProxyConfiguration.Builder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.Builder.html)>` 的 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` 实例
<a name="http-config-url-multi-clients"></a>

为了帮助降低应用程序的资源和内存使用量，您可以配置 `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` 和 `ApacheHttpClient` 一起使用
<a name="http-config-url-caveat"></a>

在应用程序中使用 `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` 构件的依赖项](http-configuration-apache.md#http-apache-dependency)。

## 代理配置示例
<a name="http-configuration-url-proxy-conf-ex"></a>

以下代码片段将[代理配置生成器用于 URL 连接 HTTP 客户端](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.Builder.html)。

```
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\$1PROXY 环境变量。