使用AWS SDK for Java 2.x 发出 AWS 服务请求 - AWS SDK for Java 2.x

使用AWS SDK for Java 2.x 发出 AWS 服务请求

使用服务客户端发出请求

完成设置 SDK 中的步骤并了解如何配置服务客户端后,您就可以向诸如 Amazon S3、Amazon DynamoDB、AWS Identity and Access Management、Amazon EC2 等 AWS 服务发出请求了。

创建服务客户端

要向 AWS 服务 发出请求,必须先使用静态工厂方法 builder() 为该服务实例化服务客户端。builder() 方法返回一个允许您自定义服务客户端的 builder 对象。常用的 setter 方法会返回 builder 对象,由此可以将方法调用组合起来,这样不仅方便而且代码更加便于阅读。在配置了所需属性后,可以调用 build() 方法创建客户端。

例如,以下代码段将 Ec2Client 对象实例化为 Amazon EC2 的服务客户端。

Region region = Region.US_WEST_2; Ec2Client ec2Client = Ec2Client.builder() .region(region) .build();
注意

开发工具包中的服务客户端是线程安全的。为了获得最佳性能,应将其作为永久对象。每个客户端自己有连接池资源,当客户端收集到垃圾时相应资源会释放。

服务客户端对象是不可变的,因此您必须为向其发出请求的每个服务创建一个新的客户端,或者,如果您希望使用不同的配置向同一服务发出请求,也需要创建一个新的客户端。

并非所有 AWS 服务都需要在服务客户端生成器中指定 Region;但是,最佳实践是为在应用程序中进行的 API 调用设置区域。有关更多信息,请参阅 AWS 区域选择

默认客户端配置

客户端生成器包含名为 create() 的另一个工厂方法。此方法将使用默认配置创建服务客户端。该客户端使用默认提供程序链加载凭证和默认 AWS 区域提供程序链。如果不能根据运行应用程序的环境确定凭证或区域,则对 create 的调用失败。有关 SDK 如何确定要使用的凭证和区域的更多信息,请参阅使用凭证区域选择

例如,以下代码段将 DynamoDbClient 对象实例化为 Amazon DynamoDB 的服务客户端。

DynamoDbClient dynamoDbClient = DynamoDbClient.create();

配置服务客户端

有关如何配置服务客户端的详细信息,请参阅通过外部方式配置客户端代码中的客户端配置

关闭服务客户端

作为最佳实践,您应该在应用程序的生命周期内使用服务客户端进行多个 API 服务调用。但是,如果您需要一次性使用服务客户端,或者不再需要该服务客户端,请将其关闭。

当不再需要服务客户端时,请调用 close() 方法,以释放资源。

ec2Client.close();

如果您需要一次性使用服务客户端,则可以通过 try-with-resources 语句将服务客户端实例化为资源。服务客户端将实现 Autoclosable 接口,因此 JDK 会在语句末尾自动调用 close() 方法。

以下示例演示如何使用服务客户端进行一次性调用。调用 AWS Security Token Service 的 StsClient 将在返回账户 ID 后关闭。

import software.amazon.awssdk.services.sts.StsClient; String getAccountID() { try (StsClient stsClient = StsClient.create()) { return stsClient.getCallerIdentity().account(); } }

提出请求

使用服务客户端向对应的 AWS 服务 提出请求。

例如,以下代码段演示如何创建 RunInstancesRequest 对象以创建新的 Amazon EC2 实例:

// Create the request by using the fluid setter methods of the request builder. RunInstancesRequest runInstancesRequest = RunInstancesRequest.builder() .imageId(amiId) .instanceType(InstanceType.T1_MICRO) .maxCount(1) .minCount(1) .build(); // Use the configured request with the service client. RunInstancesResponse response = ec2Client.runInstances(runInstancesRequest);

SDK 并不创建请求并在实例中传递,而是提供可用于创建请求的 fluent API。借助 fluent API,您可以使用 Java lambda 表达式创建请求“内联”。

以下示例使用通过生成器创建请求的 runInstances 方法版本重写了前面的示例。

// Create the request by using a lambda expression. RunInstancesResponse response = ec2.runInstances(r -> r .imageId(amiId) .instanceType(InstanceType.T1_MICRO) .maxCount(1) .minCount(1));

使用请求来覆盖客户端配置

尽管服务客户端是不可变的,但您可以在请求级别覆盖它的许多设置。在构建请求时,您可以使用 AwsRequestOverrideConfiguration 实例来提供覆盖设置。可以用来覆盖客户端设置的一些方法包括:

  • apiCallAttemptTimeout

  • apiCallTimeout

  • credentialProvider

  • compressionConfiguration

  • putHeader

查看使用请求覆盖客户端设置的示例时,假设您有以下使用默认设置的 S3 客户端。

S3Client s3Client = S3Client.create();

您想下载一个大文件,并希望确保在下载完成之前请求不会超时。为此,请仅增大单个 GetObject 请求的超时值,如以下代码所示。

Standard API
AwsRequestOverrideConfiguration overrideConfiguration = AwsRequestOverrideConfiguration.builder() .apiCallTimeout(Duration.ofSeconds(100L)) .apiCallAttemptTimeout(Duration.ofSeconds(25L)) .build(); GetObjectRequest request = GetObjectRequest.builder() .bucket("amzn-s3-demo-bucket") .key("demo-key") .overrideConfiguration(overrideConfiguration) .build(); s3Client.getObject(request, myPath);
Fluent API
s3Client.getObject(b -> b .bucket("amzn-s3-demo-bucket") .key("demo-key") .overrideConfiguration(c -> c .apiCallTimeout(Duration.ofSeconds(100L)) .apiCallAttemptTimeout(Duration.ofSeconds(25L))), myPath);

处理回复

对于大多数服务操作,SDK 会返回响应对象。您的代码可以根据需求处理响应对象中的信息。

例如,以下代码段输出上一个请求中随 RunInstancesResponse 对象返回的第一个实例 ID。

RunInstancesResponse runInstancesResponse = ec2Client.runInstances(runInstancesRequest); System.out.println(runInstancesResponse.instances().get(0).instanceId());

但是,并非所有操作都会返回包含服务特定数据的响应对象。在这些情况下,您可以查询 HTTP 响应状态以了解操作是否成功。

例如,以下代码段中的代码会检查 HTTP 响应,以查看 Amazon Simple Email Service 的 DeleteContactList 操作是否成功。

SesV2Client sesv2Client = SesV2Client.create(); DeleteContactListRequest request = DeleteContactListRequest.builder() .contactListName("ExampleContactListName") .build(); DeleteContactListResponse response = sesv2Client.deleteContactList(request); if (response.sdkHttpResponse().isSuccessful()) { System.out.println("Contact list deleted successfully"); } else { System.out.println("Failed to delete contact list. Status code: " + response.sdkHttpResponse().statusCode()); }