

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 建立簡單的應用程式 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 開發套件的[單一登入存取設定開發環境](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`和建立 stub 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_tw/sdk-for-java/latest/developer-guide/get-started-tutorial.html)

1. 輸入最後一個值後，Maven 會列出您所做的選擇。輸入 來確認，*`Y`*或輸入 來重新輸入值*`N`*。

Maven `getstarted`會根據您輸入的`artifactId`值建立名為 的專案資料夾。在 `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`*會以程式碼取代 。

### `Handler` 類別，Maven 產生的
<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()`方法中建立儲存貯體後，程式會使用 的 [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))方法上傳物件`S3Client`。物件的內容是使用 `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) 
+  [使用其他 Amazon Web Services](work-with-services.md) ，例如 [DynamoDB](examples-dynamodb.md)、 [Amazon EC2](examples-ec2.md)和[各種資料庫服務](examples-databases.md) 
+  [使用 SDK](using.md) 
+  [的安全性 適用於 Java 的 AWS SDK](security.md) **