

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

# 使用创建简单的应用程序 AWS SDK for Java 2.x
<a name="get-started-tutorial"></a>

本教程向您展示了如何使用 [Apache Maven](https://maven.apache.org/) 为适用于 Java 的 SDK 2.x 定义依赖项，然后编写用于连接 Amazon S3 以上传文件的代码。

要完成本教程，请执行以下步骤：
+  [步骤 1：为本教程进行设置](#get-started-setup) 
+  [步骤 2：创建项目](#get-started-projectsetup) 
+  [步骤 3：编写代码](#get-started-code) 
+  [步骤 4：构建并运行应用程序](#get-started-run) 

## 步骤 1：为本教程进行设置
<a name="get-started-setup"></a>

在开始本教程之前，您需要满足以下条件：
+ 访问权限 Amazon S3
+ 配置为 AWS 服务 使用单点登录访问的 Java 开发环境 AWS IAM Identity Center

请按照 [设置概述](setup.md#setup-overview) 中的说明为本教程进行设置。在[将开发环境配置为 Java SDK 的单点登录访问权限](get-started-auth.md#setup-credentials)并且[AWS 访问门户会话处于活动状态](get-started-auth.md#setup-login-sso)后，请继续本教程的步骤 2。

## 步骤 2：创建项目
<a name="get-started-projectsetup"></a>

要为本教程创建项目，您需要运行一条 Maven 命令，该命令会提示您输入有关如何配置项目的信息。完成所有输入并进行确认后，Maven 通过创建 `pom.xml` 完成项目构建，并创建存根 Java 文件。

1. 打开终端或命令提示符窗口，然后导航到您选择的目录，例如您的 `Desktop` 或 `Home` 文件夹。

1. 在终端中输入以下命令，然后按 `Enter`。

   ```
   mvn archetype:generate \
     -DarchetypeGroupId=software.amazon.awssdk \
     -DarchetypeArtifactId=archetype-app-quickstart \
     -DarchetypeVersion=2.27.21
   ```

1. 为每个提示输入第二列中列出的值。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/get-started-tutorial.html)

1. 输入最后一个值后，Maven 会列出您所做的选择。通过输入 *`Y`* 进行确认，或者通过输入 *`N`* 重新输入值。

Maven 会根据您输入的 `artifactId` 值创建名为 `getstarted` 的项目文件夹。在 `getstarted` 文件夹中，找到一个可以查看的 `README.md` 文件、一个 `pom.xml` 文件和一个 `src` 目录。

Maven 构建了以下目录树。

```
getstarted
├── README.md
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── org
    │   │       └── example
    │   │           ├── App.java
    │   │           ├── DependencyFactory.java
    │   │           └── Handler.java
    │   └── resources
    │       └── simplelogger.properties
    └── test
        └── java
            └── org
                └── example
                    └── HandlerTest.java

10 directories, 7 files
```

下面显示的是 `pom.xml` 项目文件的内容。

### `pom.xml`
<a name="projectsetup-collapse2"></a>

`dependencyManagement` 部分包含一个 AWS SDK for Java 2.x 依赖项，而 `dependencies` 部分包含一个 Amazon S3 依赖项。由于 `maven.compiler.source` 和 `maven.compiler.target` 属性中的值是 `1.8`，所以该项目使用 Java 1.8。

```
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>getstarted</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.shade.plugin.version>3.2.1</maven.shade.plugin.version>
        <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version>
        <exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
        <aws.java.sdk.version>2.27.21</aws.java.sdk.version> <-------- SDK version picked up from archetype version.
        <slf4j.version>1.7.28</slf4j.version>
        <junit5.version>5.8.1</junit5.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.java.sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>  <-------- S3 dependency
            <exclusions>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>netty-nio-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>apache-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>sso</artifactId> <-------- Required for identity center authentication.
        </dependency>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>ssooidc</artifactId> <-------- Required for identity center authentication.
        </dependency>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>apache-client</artifactId> <-------- HTTP client specified.
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <!-- Needed to adapt Apache Commons Logging used by Apache HTTP Client to Slf4j to avoid
        ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl during runtime -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit5.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
            </plugin>
        </plugins>
    </build>

</project>
```

## 步骤 3：编写代码
<a name="get-started-code"></a>

以下代码显示的是 Maven 创建的 `App` 类。`main` 方法是应用程序的入口点，它会创建 `Handler` 类的实例，然后调用其 `sendRequest` 方法。

### `App` 类
<a name="projectsetup-collapse2"></a>

```
package org.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class App {
    private static final Logger logger = LoggerFactory.getLogger(App.class);

    public static void main(String... args) {
        logger.info("Application starts");

        Handler handler = new Handler();
        handler.sendRequest();

        logger.info("Application ends");
    }
}
```

Maven 创建的 `DependencyFactory` 类包含用于构建和返回 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html) 实例的 `s3Client` 工厂方法。`S3Client` 实例使用基于 Apache 的 HTTP 客户端的实例。这是因为您在 Maven 提示您输入使用哪个 HTTP 客户端时指定了 `apache-client`。

以下代码中显示了 `DependencyFactory`。

### `DependencyFactory` 类
<a name="code-collapse2"></a>

```
package org.example;

import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.services.s3.S3Client;

/**
 * The module containing all dependencies required by the {@link Handler}.
 */
public class DependencyFactory {

    private DependencyFactory() {}

    /**
     * @return an instance of S3Client
     */
    public static S3Client s3Client() {
        return S3Client.builder()
                       .httpClientBuilder(ApacheHttpClient.builder())
                       .build();
    }
}
```

`Handler` 类包含程序的主要逻辑。在 `App` 类中创建 `Handler` 的实例时，`DependencyFactory` 将提供 `S3Client` 服务客户端。您的代码使用 `S3Client` 实例调用 Amazon S3 服务。

Maven 生成以下带有 `TODO` 注释的 `Handler` 类。本教程的下一步会将 *`TODO`* 替换为代码。

### Maven 生成的 `Handler` 类
<a name="code-collapsible3"></a>

```
package org.example;

import software.amazon.awssdk.services.s3.S3Client;


public class Handler {
    private final S3Client s3Client;

    public Handler() {
        s3Client = DependencyFactory.s3Client();
    }

    public void sendRequest() {
        // TODO: invoking the api calls using s3Client.
    }
}
```

要填写逻辑，请将该 `Handler` 类的全部内容替换为以下代码。这将填写 `sendRequest` 方法并添加必要的导入。

### 实现的 `Handler` 类
<a name="code-collapse4"></a>

该代码首先创建一个新的 S3 桶，其名称的最后一部分使用 `System.currentTimeMillis()` 生成，以使桶名称具有唯一性。

使用 `createBucket()` 方法创建桶后，程序将使用 `S3Client` 的 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#putObject(software.amazon.awssdk.services.s3.model.PutObjectRequest,software.amazon.awssdk.core.sync.RequestBody)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#putObject(software.amazon.awssdk.services.s3.model.PutObjectRequest,software.amazon.awssdk.core.sync.RequestBody)) 方法上传对象。对象的内容是使用 `RequestBody.fromString` 方法创建的简单字符串。

最后，程序使用 `cleanUp` 方法删除对象，然后删除桶。

```
package org.example;

import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
import software.amazon.awssdk.services.s3.model.DeleteBucketRequest;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;


public class Handler {
    private final S3Client s3Client;

    public Handler() {
        s3Client = DependencyFactory.s3Client();
    }

    public void sendRequest() {
        String bucket = "bucket" + System.currentTimeMillis();
        String key = "key";

        createBucket(s3Client, bucket);

        System.out.println("Uploading object...");

        s3Client.putObject(PutObjectRequest.builder().bucket(bucket).key(key)
                        .build(),
                RequestBody.fromString("Testing with the {sdk-java}"));

        System.out.println("Upload complete");
        System.out.printf("%n");

        cleanUp(s3Client, bucket, key);

        System.out.println("Closing the connection to {S3}");
        s3Client.close();
        System.out.println("Connection closed");
        System.out.println("Exiting...");
    }

    public static void createBucket(S3Client s3Client, String bucketName) {
        try {
            s3Client.createBucket(CreateBucketRequest
                    .builder()
                    .bucket(bucketName)
                    .build());
            System.out.println("Creating bucket: " + bucketName);
            s3Client.waiter().waitUntilBucketExists(HeadBucketRequest.builder()
                    .bucket(bucketName)
                    .build());
            System.out.println(bucketName + " is ready.");
            System.out.printf("%n");
        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }

    public static void cleanUp(S3Client s3Client, String bucketName, String keyName) {
        System.out.println("Cleaning up...");
        try {
            System.out.println("Deleting object: " + keyName);
            DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder().bucket(bucketName).key(keyName).build();
            s3Client.deleteObject(deleteObjectRequest);
            System.out.println(keyName + " has been deleted.");
            System.out.println("Deleting bucket: " + bucketName);
            DeleteBucketRequest deleteBucketRequest = DeleteBucketRequest.builder().bucket(bucketName).build();
            s3Client.deleteBucket(deleteBucketRequest);
            System.out.println(bucketName + " has been deleted.");
            System.out.printf("%n");
        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        System.out.println("Cleanup complete");
        System.out.printf("%n");
    }
}
```

## 步骤 4：构建并运行应用程序
<a name="get-started-run"></a>

在创建了包含完整 `Handler` 类的项目后，生成并运行该应用程序。

1. 确保您的 IAM Identity Center 会话处于活动状态。为此，请运行 AWS Command Line Interface 命令`aws sts get-caller-identity`并检查响应。如果您没有活动会话，请参阅[此部分](get-started-auth.md#setup-login-sso)了解说明。

1. 打开终端或命令提示符窗口并导航至您的项目目录 `getstarted`。

1. 使用以下命令生成项目：

   ```
   mvn clean package
   ```

1. 使用以下命令运行应用程序。

   ```
   mvn exec:java -Dexec.mainClass="org.example.App"
   ```

要查看程序创建的新桶和对象，请执行以下步骤。

1. 在 `Handler.java` 中，注释掉 `sendRequest` 方法中的 `cleanUp(s3Client, bucket, key)` 行并保存文件。

1. 运行 `mvn clean package` 以重新生成项目。

1. 重新运行 `mvn exec:java -Dexec.mainClass="org.example.App"` 以再次上传文本对象。

1. 登录 [S3 控制台](https://console.aws.amazon.com/s3/)，在新创建的桶中查看新对象。

查看文件后，删除对象，然后删除桶。

### 成功
<a name="get-started-success"></a>

如果您的 Maven 项目生成和运行都没有错误，那么恭喜您！您已经使用适用于 Java 的 SDK 2.x 成功构建了您的第一个 Java 应用程序。

### 清理
<a name="cleanup"></a>

要清除您在本教程中创建的资源，请执行以下操作：
+ 在 [S3 控制台](https://console.aws.amazon.com/s3/)中删除运行应用程序时创建的所有对象和所有桶（如果您尚未执行此操作）。
+ 删除项目文件夹 (`getstarted`)。

## 后续步骤
<a name="get-started-next"></a>

现在您已掌握了基础知识，接下来，您可以了解以下内容：
+  [与 Amazon S3](examples-s3.md) 
+  [使用其他](work-with-services.md)（例如 Amazon Web Services[DynamoDB[Amazon EC2](examples-ec2.md)](examples-dynamodb.md)、）和[各种数据库服务](examples-databases.md) 
+  [使用 SDK](using.md) 
+  [适用于 Java 的 AWS SDK的安全性](security.md)**