

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

# 在AWS SDK for Java 2.x 中配置客户端端点
<a name="endpoint-config"></a>

适用于 Java 的 SDK 2.x 提供了多种配置服务端点的方法。端点是 SDK 用来向 AWS 服务进行 API 调用的 URL。默认情况下，SDK 会根据您配置的 AWS 区域自动为每项服务确定适合的端点。但在某些情况下，您可能需要自定义或覆盖这些端点：
+ 使用本地或第三方服务实现（例如 LocalStack）
+ 通过代理或 VPC 端点连接到 AWS 服务
+ 针对测试版或预发布版服务端点进行测试

## 端点配置选项
<a name="endpoint-configuration-options"></a>

 AWS SDK for Java 2.x 提供了几种配置端点的方法：
+ 使用服务客户端生成器进行代码内配置
+ 使用环境变量进行外部配置
+ 使用 JVM 系统属性进行外部配置
+ 使用共享 AWS 配置文件进行外部配置

## 代码内端点配置
<a name="in-code-endpoint-configuration"></a>

### 使用 `endpointOverride`
<a name="endpoint-override"></a>

 配置端点的最直接方法是在服务客户端生成器中使用 `endpointOverride` 方法。此方法接受表示自定义端点 URL 的 `URI` 对象。

**Example 为 Amazon S3 客户端设置自定义端点**  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import java.net.URI;

S3Client s3 = S3Client.builder()
        .region(Region.US_WEST_2)
        .endpointOverride(URI.create("https://my-custom-s3-endpoint.example.com"))
        .build();
```

使用 `endpointOverride` 时，即使已明确设置端点，您仍必须为客户端指定区域。区域用于对请求进行签名。

### 端点发现
<a name="endpoint-discovery"></a>

有些 AWS 服务支持端点发现，SDK 可以自动发现要使用的最佳端点。您可以在服务客户端生成器中使用 `endpointDiscoveryEnabled` 方法来启用或禁用此功能。

**Example 为 DynamoDB 客户端启用端点发现**  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;

DynamoDbClient dynamoDb = DynamoDbClient.builder()
        .region(Region.US_WEST_2)
        .endpointDiscoveryEnabled(true)
        .build();
```

## 请求级别端点配置
<a name="request-level-endpoint-configuration"></a>

在某些情况下，您可能需要覆盖特定请求的端点，而为其他具有默认端点的请求使用相同的客户端。AWS SDK for Java 2.x 通过请求覆盖来支持此功能。

**Example 覆盖特定请求的端点**  

```
import software.amazon.awssdk.core.SdkRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.http.SdkHttpRequest;

S3Client s3 = S3Client.builder()
        .region(Region.US_WEST_2)
        .build();

// Create a request
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
        .bucket("amzn-s3-demo-bucket")
        .key("my-key")
        .overrideConfiguration(c -> c.putHeader("Host", "custom-endpoint.example.com"))
        .build();

// Execute the request with the custom endpoint
s3.getObject(getObjectRequest);
```

请注意，请求级别的端点覆盖受到限制，可能并不适用于所有服务或场景。在大多数情况下，建议使用客户端级别端点配置。

## 外部端点配置
<a name="external-endpoint-configuration"></a>

### 使用环境变量
<a name="environment-variables-for-endpoints"></a>

您可以使用环境变量来配置端点。SDK 支持通过 `AWS_ENDPOINT_URL_[SERVICE]` 格式的环境变量来配置服务特定的端点，其中 `[SERVICE]` 是大写服务标识符。

**Example 使用环境变量设置 S3 端点**  

```
# For Linux/macOS
export AWS_ENDPOINT_URL_S3=https://my-custom-s3-endpoint.example.com

# For Windows
set AWS_ENDPOINT_URL_S3=https://my-custom-s3-endpoint.example.com
```

 您还可以使用以下环境变量设置全局端点 URL 前缀或后缀：
+ `AWS_ENDPOINT_URL` - 为所有服务设置全局端点
+ `AWS_ENDPOINT_URL_PREFIX` - 为所有服务端点添加前缀
+ `AWS_ENDPOINT_URL_SUFFIX` - 为所有服务端点添加后缀

### 使用 JVM 系统属性
<a name="jvm-system-properties-for-endpoints"></a>

 您也可以使用 JVM 系统属性来配置端点。其格式与环境变量类似，但使用不同的命名约定。

**Example 使用 JVM 系统属性设置 S3 端点**  

```
java -Daws.endpointUrl.s3=https://my-custom-s3-endpoint.example.com -jar your-application.jar
```

 也可以通过系统属性进行全局端点配置：
+ `aws.endpointUrl` - 为所有服务设置全局端点
+ `aws.endpointUrl.prefix` - 为所有服务端点添加前缀
+ `aws.endpointUrl.suffix` - 为所有服务端点添加后缀

### 使用共享 AWS 配置文件
<a name="aws-config-file-for-endpoints"></a>

 AWS SDK for Java 2.x 还支持通过共享 AWS 配置文件进行端点配置，该文件通常位于 `~/.aws/config`（Linux/macOS）或 `%USERPROFILE%\.aws\config`（Windows）。有关信息和示例，请参阅《[AWS SDK 和工具参考指南](https://docs.aws.amazon.com/sdkref/latest/guide/feature-ss-endpoints.html#ss-endpoints-config)》。

## 配置优先级
<a name="endpoint-configuration-precedence"></a>

 当存在多个端点配置时，SDK 遵循以下优先顺序（从最高到最低）：

1. 请求级别覆盖（如果适用）

1. 通过 `endpointOverride` 进行客户端级别配置

1. 环境变量

1. JVM 系统属性

1. 共享 AWS 配置文件

1. 基于已配置 AWS 区域的默认端点

## 特定于服务的端点配置
<a name="service-specific-endpoint-configuration"></a>

 有些 AWS 服务还具有特定于该服务的额外端点配置选项。下面是几个示例：

### Amazon S3 端点配置
<a name="s3-endpoint-configuration"></a>

 Amazon S3 通过 `S3Configuration` 类支持几种端点配置：
+ `dualstackEnabled` - 启用 IPv6 支持
+ `accelerateModeEnabled` - 启用 S3 Transfer Acceleration
+ `pathStyleAccessEnabled` - 使用路径风格访问方式而不是虚拟托管风格
+ `useArnRegionEnabled` - 为跨区域请求使用 ARN 中的区域
+ `fipsModeEnabled` - 将请求路由到符合 FIPS 标准的端点

**Example 配置特定于 S3 的端点选项**  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Configuration;

S3Client s3 = S3Client.builder()
        .region(Region.US_WEST_2)
        .serviceConfiguration(S3Configuration.builder()
                .accelerateModeEnabled(true)
                .dualstackEnabled(true)
                .pathStyleAccessEnabled(false)
                .fipsModeEnabled(true)
                .build())
        .build();
```

### DynamoDB 端点配置
<a name="dynamodb-endpoint-configuration"></a>

 对于 DynamoDB，您可能需要使用端点发现或连接到 [DynamoDB local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html) 进行测试：

**Example 连接到 DynamoDB local**  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import java.net.URI;

DynamoDbClient dynamoDb = DynamoDbClient.builder()
        .endpointOverride(URI.create("http://localhost:8000"))
        // The region is meaningless for DynamoDB local but required for the client builder.
        .region(Region.US_WEST_2)
        .build();
```

DynamoDB 还支持使用[基于账户的端点](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html)，您可以在代码中配置或使用外部设置进行配置。以下示例说明如何在创建客户端时在代码中禁用基于账户的端点（默认设置为*首选*）：

```
DynamoDbClient dynamoDbClient = DynamoDbClient.builder()
    .region(Region.US_EAST_1)
    .accountIdEndpointMode(AccountIdEndpointMode.DISABLED)
    .build();
```

## 最佳实践
<a name="endpoint-configuration-best-practices"></a>

 在AWS SDK for Java 2.x 中配置端点时，请考虑以下最佳实践：
+  *为环境特定的端点使用外部配置* - 使用环境变量、系统属性或 AWS 配置文件来配置不同环境（开发、测试、生产）的端点。
+  *对特定于应用程序的端点使用代码内配置* - 使用客户端生成器的 `endpointOverride` 方法来处理特定于应用程序设计的端点。
+  *始终指定区域* - 即使在覆盖端点时，也始终指定用于请求签名的区域。
+  *请谨慎使用全局端点覆盖* - 使用全局端点覆盖会影响所有服务，而这可能不是您想要的结果。
+  *考虑安全影响* - 使用自定义端点时，请确保为这些端点采取了适当的安全措施，尤其是对于生产工作负载。