

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

# 從 1.x 版遷移至 2.x 版 適用於 Java 的 AWS SDK
<a name="migration"></a>

The 適用於 Java 的 AWS SDK 2.x 是建置在 Java 8\$1 之上的 1.x 程式碼基礎的主要重寫。其中包括許多更新，例如提升一致性、簡單易用，以及大幅強化的不變性。本節說明 2.x 版中的新主要功能，並提供如何將程式碼從 1.x 遷移至 2.x 版的指引。

**Topics**
+ [

## 第 2 版的新功能
](#migration-whats-new)
+ [使用 1.x 用戶端尋找應用程式](migration-find-apps-using-v1.md)
+ [如何遷移](migration-howto.md)
+ [1.x 和 2.x 之間的差異](migration-whats-different.md)
+ [

# side-by-side使用適用於 Java 的 開發套件 1.x 和 2.x
](migration-side-by-side.md)

## 第 2 版的新功能
<a name="migration-whats-new"></a>
+ 您可以設定自己的 HTTP 用戶端。請參閱 [HTTP 傳輸組態](http-configuration.md)。
+ 非同步用戶端具有非封鎖 I/O 支援和傳回`CompletableFuture`物件的功能。請參閱[非同步程式設計](asynchronous.md)。
+ 傳回多個頁面的操作自動以分頁格式回應。如此一來，您就可以將程式碼專注於如何處理回應，而無需檢查並取得後續頁面。請參閱[分頁](pagination.md)。
+  AWS Lambda 函數的 SDK 開始時間效能已改善。請參閱 [SDK 開始時間效能改進](lambda-optimize-starttime.md)。
+ 2.x 版支援建立請求的新速記法。  
**Example**  

  ```
  dynamoDbClient.putItem(request -> request.tableName(TABLE))
  ```

如需新功能的詳細資訊，以及查看特定程式碼範例，請參閱本指南的其他章節。
+  [Quick Start](get-started.md) 
+  [設定](setup.md) 
+  [適用於 Java 的 AWS SDK 2.x 的程式碼範例 ](java_code_examples.md)
+  [使用 SDK](using.md) 
+  [的安全性 適用於 Java 的 AWS SDK](security.md) 

# 使用 適用於 Java 的 AWS SDK 1.x 用戶端尋找應用程式
<a name="migration-find-apps-using-v1"></a>

在遷移至 之前 AWS SDK for Java 2.x，您需要識別環境中哪些應用程式使用適用於 Java 的 SDK 1.x 用戶端。您可以使用 CloudTrail 日誌來追蹤 SDK 用量、搜尋應用程式日誌以取得棄用警告、檢查您的原始程式碼和建置組態，或檢查您的可部署 Java 成品。使用您環境中可用的任何方法。

## 使用 CloudTrail Lake 尋找具有 1.x 用戶端的應用程式
<a name="migration-find-v1-apps-with-cloudtrail"></a>

AWS CloudTrail Lake 可讓您查詢 CloudTrail 記錄的事件。請依照下列步驟建立資料湖，以識別應用程式使用的 SDK 版本：

1. 建立 CloudTrail 資料湖。請參閱 [使用者指南](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/query-event-data-store.html)以建立事件資料存放區。

1. 建立資料存放區之後，請檢查記錄內容。記錄內文包含決定請求動作、時間和位置的欄位。如需詳細資訊，請參閱 [ CloudTrail 記錄內容的使用者指南](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.html)。

1. 針對您的資料執行查詢。遵循 [使用者指南來查詢和儲存查詢結果](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/query-run-query.html)。

每個記錄中的 *userAgent* 欄位都包含提出請求的 SDK 版本。使用此欄位來識別使用適用於 Java 的 SDK 1.x 的應用程式。

下列範例查詢會尋找從 2025 年 6 月 17 日開始針對 EventDatastoreID 使用適用於 Java 的 SDK 1.x 提出的使用者應用程式和第三方工具的所有請求`sample-Data-Store-Id`：

```
select userIdentity, eventSource, awsRegion,
    eventName, eventType, eventTime, userAgent,
    requestParameters, sourceIPAddress
 from sample-Data-Store-Id
where eventTime > '2025-06-17 00:00:00'
and userAgent like '%aws-sdk-java/1.%'
and userAgent not like '%aws-internal/%'
order by eventTime desc
```

查詢結果中的事件內容範例如下所示：

```
{
    "userIdentity": "{
         "type": "IAMUser",
         "principalId": "AIDAJ45Q7YFFAREXAMPLE",
         "arn": "arn:aws:iam::123456789012:user/Alice",
         "accountId": "123456789012",
         "accessKeyId": "",
         "userName": "Alice"
    }",
    "eventSource": "dynamodb.amazonaws.com",
    "awsRegion": "us-west-2",
    "eventName": "ListTables",
    "eventType": "AwsApiCall",
    "eventTime": "2025-07-01 02:23:52.000",
    "userAgent": "aws-sdk-java/1.12.746 Linux/5.10.240 OpenJDK/11.0.25+9-LTS ...",
    "requestParameters": "",
    "sourceIPAddress": "12.345.6.78"
}
```

您可以使用此資訊來協助判斷提出請求的時間和位置。

在此範例中，DynamoDB `ListTables`請求是從 IP 地址`2025-07-01 02:23:52 (UTC)`發出，`12.345.6.78`其憑證為名為 Alice 的 IAM 使用者。*userAgent* 欄位的值顯示請求是使用`1.12.746`具有 JDK 11 的 Linux 系統 適用於 Java 的 AWS SDK 版本提出的。

如需 AWS CloudTrail 事件記錄中欄位的說明，請參閱適用於[管理、資料和網路活動事件的 CloudTrail 記錄內容](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.html)。

如果您的帳戶中未啟用 CloudTrail，請聯絡組織的 AWS 帳戶管理員來啟用 CloudTrail，或使用下列各節所述的替代方法之一。

CloudTrail Lake 會針對每個查詢擷取的資料和掃描的資料收取費用。若要將成本降至最低，請篩選特定時間範圍和區域的查詢。要了解目前的定價資訊，請參閱 [AWS CloudTrail 定價](https://aws.amazon.com/cloudtrail/pricing/)。

## 搜尋 SDK 取代的應用程式警告層級日誌
<a name="migration-find-v1-apps-log-warning"></a>

從 1.12.767 版 (2024 年 7 月 30 日發行） 開始， 適用於 Java 的 AWS SDK 1.x 會在應用程式啟動時發出棄用警告。您可以搜尋應用程式日誌以取得此警告，以識別哪些應用程式和主機正在使用適用於 Java 的 SDK 1.x。

警告的確切措辭取決於 SDK 版本：
+ 版本 1.12.767 到 1.12.796：

  `WARNING: The AWS SDK for Java 1.x entered maintenance mode starting July 31, 2024 and will reach end of support on December 31, 2025...`
+ 1.12.797 版及更新版本：

  `WARNING: The AWS SDK for Java 1.x reached end of support on December 31, 2025...`

以下`...`指出警告訊息會繼續其他文字。您可以搜尋通用字首`The AWS SDK for Java 1.x`來尋找任一版本的警告。

下列範例示範如何使用 搜尋此警告`grep`：

```
grep -r "The AWS SDK for Java 1.x" /path/to/your/application/logs/
```

如果找到警告，`grep`命令會列印相符的日誌行。如果找不到警告，表示您的應用程式未使用適用於 Java 的 SDK 1.x，或使用早於 1.12.767 的版本。在這種情況下，請使用本文件所述的其他方法之一。

## 搜尋原始程式碼和相依性
<a name="migration-find-v1-apps-source-code"></a>

您可以搜尋程式碼庫並建置組態檔案，以取得 適用於 Java 的 AWS SDK 1.x 的參考。金鑰識別符是`com.amazonaws`群組 ID，供所有適用於 Java 的 SDK 1.x 成品使用。

下列範例示範如何使用 `grep`搜尋常見 Java 專案檔案的`com.amazonaws`參考。

**範例：搜尋適用於 Java 1.x 的 SDK 匯入的 Java 來源檔案 （從專案根目錄執行）**

```
grep -r "import com.amazonaws" --include="*.java" .
```

輸出範例：

```
src/main/java/com/example/App.java:import com.amazonaws.services.s3.AmazonS3;
```

**注意**  
此`com.amazonaws`套件也供不屬於適用於 Java 的 SDK 1.x 的程式庫使用，例如 `aws-lambda-java-core`。若要確認匯入來自適用於 Java 的 SDK 1.x，請檢查 `pom.xml`、 `build.gradle`或 相依性管理組態中的對應成品 ID 是否以 開頭`aws-java-sdk-`。

**範例：搜尋適用於 Java 1.x 的 SDK 相依性的 Maven `pom.xml` 檔案 （從專案根目錄執行）**

```
grep -r "com.amazonaws" --include="pom.xml" .
```

輸出範例：

```
pom.xml:    <groupId>com.amazonaws</groupId>
```

**範例：搜尋適用於 Java 的 SDK 1.x 相依性的 Gradle 建置檔案 （從專案根目錄執行）**

```
grep -r "com.amazonaws:aws-java-sdk" --include="*.gradle" .
```

輸出範例：

```
build.gradle:    implementation 'com.amazonaws:aws-java-sdk-s3:1.12.xxx'
```

上述`grep`命令會識別直接在您的來源和建置檔案中宣告的適用於 Java 1.x 的 SDK 參考。不過，您的應用程式也可能暫時依賴適用於 Java 的 SDK 1.x - 透過第三方程式庫，而該程式庫本身依賴於 SDK。使用建置工具的相依性樹狀目錄，尋找適用於 Java 1.x 的直接和可轉移 SDK 相依性。選擇符合您建置系統的範例。

**範例：使用 Maven 來尋找所有適用於 Java 1.x 的可轉移 SDK 相依性 （從專案根目錄執行）**

```
mvn dependency:tree -Dincludes=com.amazonaws
```

輸出範例：

```
[INFO] com.example:my-application:jar:1.0-SNAPSHOT
[INFO] +- com.amazonaws:aws-java-sdk-s3:jar:1.12.746:compile
[INFO] |  \- com.amazonaws:aws-java-sdk-core:jar:1.12.746:compile
[INFO] \- some.thirdparty:library:jar:2.3.1:compile
[INFO]    \- com.amazonaws:aws-java-sdk-dynamodb:jar:1.12.600:compile
```

`-Dincludes=com.amazonaws` 旗標會篩選樹狀結構，以僅顯示適用於 Java 1.x 成品的 SDK。在此範例中， `aws-java-sdk-s3` 是直接相依性，但`aws-java-sdk-dynamodb`是由 引入的暫時性相依性`some.thirdparty:library`。

**範例：使用 Gradle 來尋找所有適用於 Java 1.x 的暫時性 SDK 相依性 （從專案根目錄執行）**

```
gradle dependencies --configuration runtimeClasspath | grep "com.amazonaws"
```

輸出範例：

```
+--- com.amazonaws:aws-java-sdk-s3:1.12.746
|    \--- com.amazonaws:aws-java-sdk-core:1.12.746
\--- com.amazonaws:aws-java-sdk-dynamodb:1.12.600
```

Gradle 沒有等同於 Maven 的內建相依性篩選條件`-Dincludes`，因此通過管道`grep`是最簡單的方法。

## 檢查可部署的 Java 成品
<a name="migration-find-v1-apps-inspect-artifacts"></a>

您可以檢查可部署的 Java 成品 (JARs、WARs 或 EARs)，以確認 適用於 Java 的 AWS SDK 1.x 是否與您的應用程式一起封裝。Java 封存檔案是 ZIP 格式檔案。若要判斷是否有適用於 Java 的 SDK 1.x，請在封存`com/amazonaws/sdk/versionInfo.properties`中尋找 檔案。此檔案包含在`aws-java-sdk-core`模組中，並包含 SDK 版本編號。

### 使用 `jar`命令快速檢查
<a name="migration-find-v1-apps-jar-command"></a>

對於在最上層合併所有相依性類別的 uber-jar，請列出封存內容並搜尋版本檔案：

在下列範例中，將 `myapp.jar`取代為應用程式 JAR 檔案的路徑。

```
jar -tf myapp.jar | grep 'versionInfo.properties'
```

如果 SDK 存在，則輸出為：

```
com/amazonaws/sdk/versionInfo.properties
```

如果您的環境無法使用 `jar`命令 （例如，僅限 JRE 或最小容器映像），您可以`unzip -l`改為使用：

```
unzip -l myapp.jar | grep 'versionInfo.properties'
```

若要列印版本：

```
unzip -p myapp.jar com/amazonaws/sdk/versionInfo.properties
```

輸出範例：

```
platform=java
version=1.12.xxx
```

**注意**  
上述命令只會搜尋 uber-jars 中的頂層項目。他們無法在精簡 JARs （其中相依性為外部） 或巢狀 JARs （例如 WARs、EARs 或 下 Lambda `lib/` 套件中的類別） 中找到開發套件類別`WEB-INF/lib/`。對於精簡 JARs，請改為檢查您的建置組態 (`pom.xml`、`build.gradle`) 或相依性樹狀目錄。對於巢狀 JARs，請使用工具來搜尋綁定JARs，該工具可以遞迴讀取 ZIP 封存，而無需擷取到磁碟。

# 如何將程式碼從 適用於 Java 的 AWS SDK 1.x 遷移至 2.x
<a name="migration-howto"></a>

您可以透過幾種方式遷移現有的適用於 Java 的 SDK 1.x 應用程式。

1. 使用[遷移工具](migration-tool.md)的自動化方法。

1. 以 2.x 匯入逐步取代 1.x 匯入的[手動方法](migration-steps.md)。

我們建議您從使用遷移工具開始。它會自動化從 1.x 到 2.x 程式碼的大部分例行替換工作。

由於工具[不會遷移所有功能](migration-tool.md#migration-tool-limitations)，因此在執行工具之後，您將需要搜尋剩餘的 v1 程式碼。當您找到工具未遷移的程式碼時，請遵循[step-by-step](migration-steps.md)（手動方法），並使用[遷移指南文章](migration-whats-different.md)來完成遷移。

**Topics**
+ [遷移工具](migration-tool.md)
+ [Step-by-step說明](migration-steps.md)

# 適用於 Java 的 AWS SDK 遷移工具
<a name="migration-tool"></a>

 適用於 Java 的 AWS SDK 提供遷移工具，可協助自動將適用於 Java 的 SDK 1.x (V1) 程式碼遷移至 2.x (V2)。此工具使用開放原始碼、原始程式碼重構工具 [OpenRewrite](https://docs.openrewrite.org/) 來執行遷移。OpenRewrite 使用程式碼修改規則 （稱為「配方」)，將您的原始程式碼從 V1 自動更新為 V2 語法和模式。

此工具支援 SDK 服務用戶端和 [S3 Transfer Manager](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/transfer/TransferManager.html) 高階程式庫的程式碼修改規則。不支援其他高階 APIs的程式碼修改規則，例如 V1 [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html)到 V2 的 [DynamoDB 增強型用戶端 API](dynamodb-enhanced-client.md)。

如需限制的詳細資訊，請參閱[此頁面的結尾](#migration-tool-limitations)。如需手動遷移步驟的常見不支援程式碼模式的詳細範例，請參閱[不支援的程式碼模式](migration-tool-unsupported-patterns.md)。

## 使用遷移工具
<a name="migration-tool-use"></a>

### 遷移 Maven 專案
<a name="migration-tool-use-maven"></a>

請依照下列指示，使用 [OpenRewrite Maven 外掛程式工具遷移適用於 Java 的 SDK 1.x Maven](https://docs.openrewrite.org/reference/rewrite-maven-plugin) 型專案。

1. 導覽至 Maven 專案的根目錄

   開啟終端機 （命令列） 視窗，然後導覽至 Maven 型應用程式的根目錄。

1. 執行外掛程式的`rewrite-maven-plugin`命令

   您可以選擇兩種模式 (Maven 目標）： `dryRun`和 `run`。

   **`dryRun`**** 模式**

   在 `dryRun`模式中，外掛程式會在主控台輸出中產生 diff 日誌，並在 `target/rewrite` 資料夾中產生名為 `rewrite.patch`的修補程式檔案。此模式可讓您預覽將要進行的變更，因為原始程式碼檔案不會進行任何變更。

   下列範例示範如何在 `dryRun` 模式中叫用 外掛程式。

   ```
   mvn org.openrewrite.maven:rewrite-maven-plugin:<rewrite-plugin-version>*:dryRun \
     -Drewrite.recipeArtifactCoordinates=software.amazon.awssdk:v2-migration:<sdkversion>** \
     -Drewrite.activeRecipes=software.amazon.awssdk.v2migration.AwsSdkJavaV1ToV2
   ```

   \$1將 *<rewrite-plugin-version>* 取代為您在此[測試檔案中](https://github.com/aws/aws-sdk-java-v2/blob/3a01289246f1f4ac814a354051d00030e53ef968/test/v2-migration-tests/src/test/java/software/amazon/awssdk/v2migrationtests/MavenTestBase.java#L54)看到`rewriteMavenPluginVersion`的值。

   \$1\$1以 2.x SDK 版本取代 *<sdkversion>*。請造訪 [Maven Central](https://central.sonatype.com/artifact/software.amazon.awssdk/v2-migration) 以檢查是否有最新版本。
**重要**  
請務必使用[測試檔案中](https://github.com/aws/aws-sdk-java-v2/blob/3a01289246f1f4ac814a354051d00030e53ef968/test/v2-migration-tests/src/test/java/software/amazon/awssdk/v2migrationtests/MavenTestBase.java#L54)`rewrite-maven-plugin`顯示的 版本，因為其他版本可能無法運作。

   來自 `dryRun` 模式的主控台輸出應該類似下列輸出。

   ```
   [WARNING] These recipes would make changes to project/src/test/resources/maven/before/pom.xml:
   [WARNING]     software.amazon.awssdk.v2migration.AwsSdkJavaV1ToV2
   [WARNING]         software.amazon.awssdk.v2migration.UpgradeSdkDependencies
   [WARNING]             org.openrewrite.java.dependencies.AddDependency: {groupId=software.amazon.awssdk, artifactId=apache-client, version=2.27.0, onlyIfUsing=com.amazonaws.ClientConfiguration}
   [WARNING]             org.openrewrite.java.dependencies.AddDependency: {groupId=software.amazon.awssdk, artifactId=netty-nio-client, version=2.27.0, onlyIfUsing=com.amazonaws.ClientConfiguration}
   [WARNING]             org.openrewrite.java.dependencies.ChangeDependency: {oldGroupId=com.amazonaws, oldArtifactId=aws-java-sdk-bom, newGroupId=software.amazon.awssdk, newArtifactId=bom, newVersion=2.27.0}
   [WARNING]             org.openrewrite.java.dependencies.ChangeDependency: {oldGroupId=com.amazonaws, oldArtifactId=aws-java-sdk-s3, newGroupId=software.amazon.awssdk, newArtifactId=s3, newVersion=2.27.0}
   [WARNING]             org.openrewrite.java.dependencies.ChangeDependency: {oldGroupId=com.amazonaws, oldArtifactId=aws-java-sdk-sqs, newGroupId=software.amazon.awssdk, newArtifactId=sqs, newVersion=2.27.0}
   [WARNING] These recipes would make changes to project/src/test/resources/maven/before/src/main/java/foo/bar/Application.java:
   [WARNING]     software.amazon.awssdk.v2migration.AwsSdkJavaV1ToV2
   [WARNING]         software.amazon.awssdk.v2migration.S3GetObjectConstructorToFluent
   [WARNING]             software.amazon.awssdk.v2migration.ConstructorToFluent
   [WARNING]         software.amazon.awssdk.v2migration.S3StreamingResponseToV2
   [WARNING]         software.amazon.awssdk.v2migration.ChangeSdkType
   [WARNING]         software.amazon.awssdk.v2migration.ChangeSdkCoreTypes
   [WARNING]             software.amazon.awssdk.v2migration.ChangeExceptionTypes
   [WARNING]                 org.openrewrite.java.ChangeType: {oldFullyQualifiedTypeName=com.amazonaws.AmazonClientException, newFullyQualifiedTypeName=software.amazon.awssdk.core.exception.SdkException}
   [WARNING]                 org.openrewrite.java.ChangeMethodName: {methodPattern=com.amazonaws.AmazonServiceException getRequestId(), newMethodName=requestId}
   [WARNING]                 org.openrewrite.java.ChangeMethodName: {methodPattern=com.amazonaws.AmazonServiceException getErrorCode(), newMethodName=awsErrorDetails().errorCode}
   [WARNING]                 org.openrewrite.java.ChangeMethodName: {methodPattern=com.amazonaws.AmazonServiceException getServiceName(), newMethodName=awsErrorDetails().serviceName}
   [WARNING]                 org.openrewrite.java.ChangeMethodName: {methodPattern=com.amazonaws.AmazonServiceException getErrorMessage(), newMethodName=awsErrorDetails().errorMessage}
   [WARNING]                 org.openrewrite.java.ChangeMethodName: {methodPattern=com.amazonaws.AmazonServiceException getRawResponse(), newMethodName=awsErrorDetails().rawResponse().asByteArray}
   [WARNING]                 org.openrewrite.java.ChangeMethodName: {methodPattern=com.amazonaws.AmazonServiceException getRawResponseContent(), newMethodName=awsErrorDetails().rawResponse().asUtf8String}
   [WARNING]                 org.openrewrite.java.ChangeType: {oldFullyQualifiedTypeName=com.amazonaws.AmazonServiceException, newFullyQualifiedTypeName=software.amazon.awssdk.awscore.exception.AwsServiceException}
   [WARNING]         software.amazon.awssdk.v2migration.NewClassToBuilderPattern
   [WARNING]             software.amazon.awssdk.v2migration.NewClassToBuilder
   [WARNING]             software.amazon.awssdk.v2migration.V1SetterToV2
   [WARNING]         software.amazon.awssdk.v2migration.V1GetterToV2
   ...
   [WARNING]         software.amazon.awssdk.v2migration.V1BuilderVariationsToV2Builder
   [WARNING]         software.amazon.awssdk.v2migration.NewClassToBuilderPattern
   [WARNING]             software.amazon.awssdk.v2migration.NewClassToBuilder
   [WARNING]             software.amazon.awssdk.v2migration.V1SetterToV2
   [WARNING]         software.amazon.awssdk.v2migration.HttpSettingsToHttpClient
   [WARNING]         software.amazon.awssdk.v2migration.WrapSdkClientBuilderRegionStr
   [WARNING] Patch file available:
   [WARNING]     project/src/test/resources/maven/before/target/rewrite/rewrite.patch
   [WARNING] Estimate time saved: 20m
   [WARNING] Run 'mvn rewrite:run' to apply the recipes.
   ```

   **`run`**** 模式**

   當您在 `run` 模式下執行外掛程式時，它會修改磁碟上的原始碼以套用變更。執行 命令之前，請確定您有原始程式碼的備份。

   下列範例示範如何在 `run` 模式中叫用 外掛程式。

   ```
   mvn org.openrewrite.maven:rewrite-maven-plugin:<rewrite-plugin-version>*:run \
     -Drewrite.recipeArtifactCoordinates=software.amazon.awssdk:v2-migration:<sdkversion>** \
     -Drewrite.activeRecipes=software.amazon.awssdk.v2migration.AwsSdkJavaV1ToV2
   ```

   \$1將 *<rewrite-plugin-version>* 取代為您在此[測試檔案中](https://github.com/aws/aws-sdk-java-v2/blob/3a01289246f1f4ac814a354051d00030e53ef968/test/v2-migration-tests/src/test/java/software/amazon/awssdk/v2migrationtests/MavenTestBase.java#L54)看到`rewriteMavenPluginVersionvalue`的 。

   \$1\$1將 *<sdkversion>* 取代為 2.x SDK 版本。請造訪 [Maven Central](https://central.sonatype.com/artifact/software.amazon.awssdk/v2-migration) 以檢查是否有最新版本。

   執行 命令後，編譯您的應用程式並執行測試以驗證變更。

### 遷移 Gradle 專案
<a name="migration-tool-use-gradle"></a>

請依照下列指示，使用 [OpenRewrite Gradle 外掛程式工具遷移適用於 Java 的 SDK 1.x Gradle](https://docs.openrewrite.org/reference/gradle-plugin-configuration) 型專案。

1. 導覽至 Gradle 專案的根目錄

   開啟終端機 （命令列） 視窗，然後導覽至 Gradle 型應用程式的根目錄。

1. 建立 Gradle init 指令碼

   在 目錄中建立具有下列內容`init.gradle`的檔案。

   ```
   initscript {
       repositories {
           maven { url "https://plugins.gradle.org/m2" }
       }
       dependencies {
           classpath("org.openrewrite:plugin:<rewrite-plugin-version>*")
       }
   }
   
   rootProject {
       plugins.apply(org.openrewrite.gradle.RewritePlugin)
       dependencies {
           rewrite("software.amazon.awssdk:v2-migration:latest.release")
       }
   
       afterEvaluate {
           if (repositories.isEmpty()) {
               repositories {
                   mavenCentral()
               }
           }
       }
   }
   ```

   \$1將 *<rewrite-plugin-version>* 取代為您在此[測試檔案中](https://github.com/aws/aws-sdk-java-v2/blob/master/test/v2-migration-tests/src/test/resources/software/amazon/awssdk/v2migrationtests/gradle/before/init.gradle#L6)看到的版本。

1. 執行 `rewrite`命令

   如同 Maven 外掛程式，您可以在 `dryRun`或 `run` 模式中執行 Gradle 外掛程式。

   **`dryRun` 模式**

   下列範例示範如何在 `dryRun` 模式中叫用 外掛程式。

   ```
   gradle rewriteDryRun --init-script init.gradle \
     -Drewrite.activeRecipes=software.amazon.awssdk.v2migration.AwsSdkJavaV1ToV2
   ```

   **`run` 模式**

   下列範例示範如何在 `run` 模式中叫用 外掛程式。

   ```
   gradle rewriteRun --init-script init.gradle \
     -Drewrite.activeRecipes=software.amazon.awssdk.v2migration.AwsSdkJavaV1ToV2
   ```

## 目前限制
<a name="migration-tool-limitations"></a>

雖然遷移透過更新至 V2 對等的程式碼修改規則來升級大多數 V1 程式碼，但某些類別和方法不會涵蓋在內。 V2 對於這些類別和方法，請依照[step-by-step指示](migration-steps.md)手動遷移您的程式碼。

對於某些不支援的程式碼修改規則，遷移工具可能會新增以下列開頭的註解：

```
/*AWS SDK for Java v2 migration: Transform for ...
```

在註解之後，工具會輸出方法或類別的 V2 版本一般 Stub。例如，在下列輸出中，遷移工具嘗試遷移 V1 S3 用戶端`setBucketLifecycleConfiguration`的方法：

```
/*AWS SDK for Java v2 migration: Transform for setBucketLifecycleConfiguration method not supported. 
Please manually migrate your code by using builder pattern, update from BucketLifecycleConfiguration.Rule 
to LifecycleRule, StorageClass to TransitionStorageClass, and adjust imports and names.*/
s3.putBucketLifecycleConfiguration(
        PutBucketLifecycleConfigurationRequest.builder()
            .bucket(bucketName)
            .lifecycleConfiguration(BucketLifecycleConfiguration.builder()
                .build())
            .build());
```

下方清單中的連結會帶您前往遷移資訊，以協助您手動遷移程式碼。
+ [第 1 版和第 2 版之間的 S3 用戶端差異 適用於 Java 的 AWS SDK](migration-s3-client.md)
+ [S3 Transfer Manager](migration-s3-transfer-manager.md) (TransferManager)
+ [DynamoDB 物件映射](migration-ddb-mapper.md) (DynamoDBMapper)
+ [EC2 中繼資料公用程式](migration-imds.md) (EC2MetadataUtils)
+ [等待程式](migration-waiters.md) (AmazonDynamoDBWaiters)
+ [IAM 政策建置器](migration-iam-policy-builder.md) （政策）
+ [CloudFront 預先簽署 ](migration-cloudfront-presigning.md)(CloudFrontUrlSigner、CloudFrontCookieSigner)
+ [S3 事件通知 ](migration-s3-event-notification.md)(S3EventNotification)
+ SDK 指標發佈 ([1.x 文件](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/generating-sdk-metrics.html)、[2.x 文件](metrics.md))
+ [不支援的程式碼模式](migration-tool-unsupported-patterns.md) – 需要手動遷移的常見程式碼模式的詳細範例

# 遷移工具不支援的程式碼模式
<a name="migration-tool-unsupported-patterns"></a>

遷移工具會自動將大多數 v1 程式碼轉換為 v2。不過，某些程式碼模式需要手動遷移。本主題提供最常見的不支援模式的詳細範例，並說明如何手動轉換。

下列模式清單並不詳盡。如果您的程式碼在執行遷移工具後未編譯，請依照[step-by-step遷移說明](migration-steps.md)手動遷移剩餘的 v1 程式碼。

## 使用參數請求物件建構函數
<a name="request-pojo-constructors"></a>

對於請求 POJOs(Amazon S3 除外），遷移工具只會轉換設定程式方法。此工具不支援具有參數的建構函數。

**支援的模式：使用設定器請求物件 （無建構器參數）**

之前 （原始 v1 程式碼）：

```
import com.amazonaws.services.sqs.model.SendMessageRequest;

SendMessageRequest request = new SendMessageRequest().withMessageBody("Hello World");
request.setQueueUrl("https://sqs.us-west-2.amazonaws.com/0123456789012/demo-queue");
```

After （遷移工具結果）：

```
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;

SendMessageRequest request = SendMessageRequest.builder()
    .messageBody("Hello World").build();
request = request.toBuilder()
    .queueUrl("https://sqs.us-west-2.amazonaws.com/0123456789012/demo-queue").build();
```

**不支援的模式：使用參數請求物件建構函數**

遷移工具無法轉換具有參數的建構函數：

在手動遷移之前，但在遷移工具之後：

```
import software.amazon.awssdk.services.sqs.model.SendMessageRequest; // Import updated to v2.

// This pattern requires manual migration.
SendMessageRequest request = new SendMessageRequest(
    "https://sqs.us-west-2.amazonaws.com/0123456789012/demo-queue", 
    "Hello World");
```

遷移工具會將匯入轉換為 v2，但建構函式程式碼保持不變，且需要手動更新才能使用建置器模式。

手動遷移之後：

```
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;

SendMessageRequest request = SendMessageRequest.builder()
    .messageBody("Hello World")
    .queueUrl("https://sqs.us-west-2.amazonaws.com/0123456789012/demo-queue")
    .build();
```

## 具有個別參數的服務用戶端方法
<a name="service-client-method-overloads"></a>

遷移工具無法轉換採用個別參數的服務用戶端方法，而非請求物件 (Amazon S3 除外）。

之前 (v1 程式碼）：

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClient;

AmazonSQS sqs = new AmazonSQSClient();
// The following v1 method takes individual parameters.
sqs.sendMessage("https://sqs.us-west-2.amazonaws.com/0123456789012/demo-queue", "Hello World");
```

After （遷移工具結果 – 未編譯）：

```
import software.amazon.awssdk.services.sqs.SqsClient;  // Import updated to v2.
// No import statement for the v2 request POJO.

SqsClient sqs = SqsClient.builder().build();

// Does not compile–v2 methods only accept request POJOs.
sqs.sendMessage("https://sqs.us-west-2.amazonaws.com/0123456789012/demo-queue", "Hello World");
```

您必須手動更新方法引數，才能使用請求物件：

```
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.SendMessageRequest; // Add manually.

SqsClient sqs = SqsClient.builder().build();

// Corrected v2 code.
SendMessageRequest request = SendMessageRequest.builder()
    .queueUrl("https://sqs.us-west-2.amazonaws.com/0123456789012/demo-queue")
    .messageBody("Hello World")
    .build();
sqs.sendMessage(request);
```

## 請求逾時方法
<a name="request-pojo-timeout-configuration"></a>

遷移工具不會轉換在請求物件上設定逾時的方法。

之前 (v1 程式碼）：

```
import com.amazonaws.services.sqs.model.SendMessageRequest;

SendMessageRequest request = new SendMessageRequest();
request.setSdkRequestTimeout(7);
```

After （遷移工具結果 – 未編譯）：

```
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;  // Import updated to v2.

SendMessageRequest request = SendMessageRequest.builder().build();

// Does not compile.
request.setSdkRequestTimeout(7);
```

您必須手動遷移以使用 v2 的 `overrideConfiguration`方法：

```
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;
import java.time.Duration;

SendMessageRequest request = SendMessageRequest.builder().build();

// Corrected v2 code.
request = request.toBuilder()
    .overrideConfiguration(o -> o.apiCallTimeout(Duration.ofSeconds(7)))
    .build();
```

## 具有參數的服務用戶端建構函數
<a name="service-client-constructors-with-args"></a>

遷移工具會轉換空的服務用戶端建構函數，但無法轉換接受登入資料或組態等參數的建構函數。

之前 (v1 程式碼）：

```
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClient;

AWSCredentials awsCredentials = new BasicAWSCredentials("akid", "skid");
AmazonSQS sqs = new AmazonSQSClient(awsCredentials);
```

After （遷移工具結果 – 未編譯）：

```
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.services.sqs.SqsClient;  // Import updated to v2.

AwsCredentials awsCredentials = AwsBasicCredentials.create("akid", "skid");

// Does not compile.
SqsClient sqs = new SqsClient(awsCredentials);
```

您必須手動更新服務用戶端建構函數，才能使用建置器模式：

```
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;  // Add manually.
import software.amazon.awssdk.services.sqs.SqsClient;

AwsCredentials awsCredentials = AwsBasicCredentials.create("akid", "skid");

// Corrected v2 code.
SqsClient sqs = SqsClient.builder()
    .credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
    .build();
```

# 遷移step-by-step說明與範例
<a name="migration-steps"></a>

本節提供step-by-step指南，將目前使用適用於 Java 的 SDK v1.x 的應用程式遷移至適用於 Java 的 SDK 2.x。第一部分提供步驟的概觀，後面接著詳細的遷移範例。

此處涵蓋的步驟說明正常使用案例的遷移，其中應用程式 AWS 服務 使用模型驅動的服務用戶端呼叫 。如果您需要遷移使用更高層級 APIs的程式碼，例如 [S3 Transfer Manager](migration-s3-transfer-manager.md) 或 [CloudFront 預先簽章](migration-cloudfront-presigning.md)，請參閱 目錄下的 [適用於 Java 的 AWS SDK 1.x 和 2.x 之間的差異](migration-whats-different.md) 一節。



此處所述的方法是建議。您可以使用其他技術，並利用 IDE 的程式碼編輯功能來達到相同的結果。

## 步驟概觀
<a name="migration-steps-overview"></a>

### 1. 首先新增適用於 Java 的 SDK 2.x BOM
<a name="migration-steps-overview-step1"></a>

透過將適用於 Java 的 SDK 2.x 的 Maven BOM （物料清單） 元素新增至您的 POM 檔案，您可以確保所需的所有 v2 相依性都來自相同的版本。POM 可以同時包含 v1 和 v2 相依性。這可讓您逐步遷移程式碼，而不是一次全部變更。

#### 適用於 Java 的 SDK 2.x BOM
<a name="drt_b5n_q1c"></a>

```
<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>
```

您可以在 Maven Central Repository 上找到[最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。

### 2. 搜尋 v1 類別匯入陳述式的檔案
<a name="migration-steps-overview-step2"></a>

透過掃描應用程式中用於 v1 匯入的 SERVICE\$1IDs的檔案，您會找到使用的唯一 SERVICE\$1IDs。SERVICE\$1ID 是 的簡短唯一名稱 AWS 服務。例如`cognitoidentity`，Amazon Cognito Identity 的 SERVICE\$1ID。

### 3. 從 v1 匯入陳述式判斷 v2 Maven 相依性
<a name="migration-steps-overview-step3"></a>

找到所有唯一的 v1 SERVICE\$1IDs之後，您可以參考 來判斷 v2 相依性的對應 Maven 成品[Maven artifactId 映射的套件名稱](#migration-serviceid-artifactid-mapping)。

### 4. 將 v2 相依性元素新增至 POM 檔案
<a name="migration-steps-overview-step4"></a>

使用步驟 3 中確定的相依性元素更新 Maven POM 檔案。

### 5. 在 Java 檔案中，在 v1 類別上逐漸變更為 v2 類別
<a name="migration-steps-overview-step5"></a>

當您將 v1 類別取代為 v2 類別時，請進行必要的變更以支援 v2 API，例如使用建置器而非建構器，以及使用流暢的 getter 和 setter。

### 6. 從 POM 移除 v1 Maven 相依性，並從檔案移除 v1 匯入
<a name="migration-steps-overview-step6"></a>

遷移程式碼以使用 v2 類別後，請從檔案移除任何剩餘的 v1 匯入，並從建置檔案移除所有相依性。

### 7. 重構程式碼以使用 v2 API 增強功能
<a name="migration-steps-overview-step7"></a>

程式碼成功編譯並通過測試後，您可以利用 v2 增強功能，例如使用不同的 HTTP 用戶端或分頁程式來簡化程式碼。此為選用步驟。

## 遷移範例
<a name="migration-steps-example"></a>

在此範例中，我們會遷移使用適用於 Java v1 的 SDK 並存取數個 的應用程式 AWS 服務。我們在步驟 5 中詳細說明下列 v1 方法。這是類別中的一種方法，其中包含八個方法，應用程式中有 32 個類別。

### 要遷移的 v1 方法
<a name="v1-snippet-collapsed"></a>

只有 v1 SDK 匯入會從 Java 檔案列出如下。

```
import com.amazonaws.ClientConfiguration;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.RegionUtils;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.AmazonEC2Exception;
import com.amazonaws.services.ec2.model.CreateTagsRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.InstanceStateName;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.ec2.model.Tag;
import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
...
private static List<Instance> getRunningInstances(AmazonEC2Client ec2, List<String> instanceIds) {
    List<Instance> runningInstances = new ArrayList<>();
    try {
        DescribeInstancesRequest request = new DescribeInstancesRequest()
                .withInstanceIds(instanceIds);
        DescribeInstancesResult result;
        do {
            // DescribeInstancesResponse is a paginated response, so use tokens with multiple requests.
            result = ec2.describeInstances(request);
            request.setNextToken(result.getNextToken());   // Prepare request for next page.
            for (final Reservation r : result.getReservations()) {
                for (final Instance instance : r.getInstances()) {
                    LOGGER.info("Examining instanceId: "+ instance.getInstanceId());
                    // if instance is in a running state, add it to runningInstances list.
                    if (RUNNING_STATES.contains(instance.getState().getName())) {
                        runningInstances.add(instance);
                    }
                }
            }
        } while (result.getNextToken() != null);
    } catch (final AmazonEC2Exception exception) {
        // if instance isn't found, assume its terminated and continue.
        if (exception.getErrorCode().equals(NOT_FOUND_ERROR_CODE)) {
            LOGGER.info("Instance probably terminated; moving on.");
        } else {
            throw exception;
        }
    }
    return runningInstances;
}
```

### 1. 新增 v2 Maven BOM
<a name="migration-steps-example-step1"></a>

將適用於 Java 的 SDK 2.x 的 Maven BOM 與 `dependencyManagement`區段中的任何其他相依性一起新增至 POM。如果您的 POM 檔案具有開發套件 v1 的 BOM，請暫時保留它。稍後的步驟會將其移除。

#### 開始時的 POM 相依性管理
<a name="migration-example-boms"></a>

```
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.example</groupId>             <!--Existing dependency in POM. -->
      <artifactId>bom</artifactId>
      <version>1.3.4</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    ...
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-java-sdk-bom</artifactId>  <!--Existing v1 BOM dependency. -->
      <version>1.11.1000</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    ...
    <dependency>
      <groupId>software.amazon.awssdk</groupId>  <!--Add v2 BOM dependency. -->
      <artifactId>bom</artifactId>
      <version>2.27.21</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
```

### 2. 搜尋 v1 類別匯入陳述式的檔案
<a name="migration-steps-example-step2"></a>

搜尋應用程式的程式碼，找出唯一出現的 `import com.amazonaws.services`。這有助於我們判斷專案使用的 v1 相依性。如果您的應用程式有列出 v1 相依性的 Maven POM 檔案，您可以改為使用此資訊。

在此範例中，我們使用 [`ripgrep`(rg)](https://github.com/BurntSushi/ripgrep) 命令來搜尋程式碼庫。

從程式碼基礎的根目錄，執行下列`ripgrep`命令。`ripgrep` 找到匯入陳述式後，這些陳述式會輸送至 `cut`、 `sort`和 `uniq`命令，以隔離 SERVICE\$1IDs。

```
rg --no-filename 'import\s+com\.amazonaws\.services' | cut -d '.' -f 4 | sort | uniq
```

對於此應用程式，下列 SERVICE\$1IDs會記錄到 主控台。

```
autoscaling
cloudformation
ec2
identitymanagement
```

這表示`import`陳述式中所使用的下列每個套件名稱至少都會出現一次。基於我們的目的，個別類別名稱並不重要。我們只需要尋找使用的 SERVICE\$1IDs。

```
com.amazonaws.services.autoscaling.*
com.amazonaws.services.cloudformation.*
com.amazonaws.services.ec2.*
com.amazonaws.services.identitymanagement.*
```

### 3. 從 v1 匯入陳述式判斷 v2 Maven 相依性
<a name="migration-steps-example-step3"></a>

我們從步驟 2 隔離的 v1 的 SERVICE\$1IDs，例如 `autoscaling`和 `cloudformation`，可以映射到大部分的相同 v2 SERVICE\$1ID。由於 v2 Maven artifactId 在大多數情況下都符合 SERVICE\$1ID，因此您擁有將相依性區塊新增至 POM 檔案所需的資訊。

下表顯示如何判斷 v2 相依性。


| v1 SERVICE\$1ID 映射至 ...套件名稱 | v2 SERVICE\$1ID 映射至 ...套件名稱 | v2 Maven 相依性 | 
| --- | --- | --- | 
|  **ec2** `com.amazonaws.services.ec2.*`  |  **ec2** `software.amazon.awssdk.services.ec2.*`  |  <pre><dependency><br />  <groupId>software.amazon.awssdk</groupId><br />  <artifactId>ec2</artifactId><br /></dependency></pre>  | 
|  **自動擴展** `com.amazonaws.services.autoscaling.*`  |  **自動擴展** `software.amazon.awssdk.services.autoscaling.*`  |  <pre><dependency><br />  <groupId>software.amazon.awssdk</groupId><br />  <artifactId>autoscaling</artifactId><br /></dependency></pre>  | 
| cloudformation`com.amazonaws.services.cloudformation.*` | cloudformation`software.amazon.awssdk.cloudformation.*` |  <pre><dependency><br />  <groupId>software.amazon.awssdk</groupId><br />  <artifactId>cloudformation</artifactId><br /></dependency></pre>  | 
| 身分管理\$1`com.amazonaws.services.identitymanagement.*` | iam\$1`software.amazon.awssdk.iam.*` |  <pre><dependency><br />  <groupId>software.amazon.awssdk</groupId><br />  <artifactId>iam</artifactId><br /></dependency></pre>  | 

\$1 `identitymanagement``iam`映射的 是例外狀況，其中 SERVICE\$1ID 在版本之間不同。如果 Maven 或 Gradle 無法解析 v2 相依性，請參閱 [Maven artifactId 映射的套件名稱](#migration-serviceid-artifactid-mapping) 以取得例外狀況。

### 4. 將 v2 相依性元素新增至 POM 檔案
<a name="migration-steps-example-step4"></a>

在步驟 3 中，我們決定了需要新增到 POM 檔案的四個相依性區塊。我們不需要新增版本，因為我們已在步驟 1 中指定 BOM。新增匯入後，我們的 POM 檔案具有下列相依性元素。

```
    ...
  <dependencies>
    ...
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>autoscaling</artifactId>
    </dependency>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>iam</artifactId>
    </dependency>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>cloudformation</artifactId>
    </dependency>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>ec2</artifactId>
    </dependency>
    ...
  </dependencies>
    ...
```

### 5. 在 Java 檔案中，在 v1 類別上逐漸變更為 v2 類別
<a name="migration-steps-example-step5"></a>

在我們遷移的方法中，我們會看到
+ 來自 的 EC2 服務用戶端`com.amazonaws.services.ec2.AmazonEC2Client`。
+ 使用的數個 EC2 模型類別。例如 `DescribeInstancesRequest`和 `DescribeInstancesResult`。

```
import com.amazonaws.ClientConfiguration;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.RegionUtils;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.AmazonEC2Exception;
import com.amazonaws.services.ec2.model.CreateTagsRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.InstanceStateName;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.ec2.model.Tag;
import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
...
private static List<Instance> getRunningInstances(AmazonEC2Client ec2, List<String> instanceIds)
    List<Instance> runningInstances = new ArrayList<>();
    try {
        DescribeInstancesRequest request = new DescribeInstancesRequest()
                .withInstanceIds(instanceIds);
        DescribeInstancesResult result;
        do {
            // DescribeInstancesResponse is a paginated response, so use tokens with multiple re
            result = ec2.describeInstances(request);
            request.setNextToken(result.getNextToken());   // Prepare request for next page.
            for (final Reservation r : result.getReservations()) {
                for (final Instance instance : r.getInstances()) {
                    LOGGER.info("Examining instanceId: "+ instance.getInstanceId());
                    // if instance is in a running state, add it to runningInstances list.
                    if (RUNNING_STATES.contains(instance.getState().getName())) {
                        runningInstances.add(instance);
                    }
                }
            }
        } while (result.getNextToken() != null);
    } catch (final AmazonEC2Exception exception) {
        // if instance isn't found, assume its terminated and continue.
        if (exception.getErrorCode().equals(NOT_FOUND_ERROR_CODE)) {
            LOGGER.info("Instance probably terminated; moving on.");
        } else {
            throw exception;
        }
    }
    return runningInstances;
}
...
```

我們的目標是將所有 v1 匯入取代為 v2 匯入。我們會一次繼續一個類別。

#### a. 取代匯入陳述式或類別名稱
<a name="migration-example-step5-substep1"></a>

我們看到 `describeRunningInstances`方法的第一個參數是 v1 `AmazonEC2Client`執行個體。執行以下任意一項：
+ 將 的匯入取代`com.amazonaws.services.ec2.AmazonEC2Client`為 `software.amazon.awssdk.services.ec2.Ec2Client`，並`AmazonEC2Client`變更為 `Ec2Client`。
+ 將參數類型變更為 ，`Ec2Client`並讓 IDE 提示我們正確匯入。我們的 IDE 會提示我們匯入 v2 類別，因為用戶端名稱不同 -`AmazonEC2Client` 和 `Ec2Client`。如果兩個版本中的類別名稱相同，則此方法無法運作。

#### b. 將 v1 模型類別取代為 v2 對等項目
<a name="migration-example-step5-substep2"></a>

變更 v2 之後`Ec2Client`，如果我們使用 IDE，我們會在下列陳述式中看到編譯錯誤。

```
                    result = ec2.describeInstances(request);
```

編譯錯誤是因為使用 v1 的 執行個體`DescribeInstancesRequest`做為 v2 `Ec2Client``describeInstances`方法的參數。若要修正，請進行下列取代或匯入陳述式。


| 取代 | 取代為 | 
| --- | --- | 
|  <pre>import com.amazonaws.services.ec2.model.DescribeInstancesRequest</pre>  |  <pre>import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest</pre>  | 

#### c. 將 v1 建構器變更為 v2 建置器。
<a name="migration-example-step5-substep3"></a>

我們仍然看到編譯錯誤，因為 [v2 類別上沒有建構函數](migration-whats-different.md#immutable-classes)。若要修正，請進行下列變更。


| 變更 | 至 | 
| --- | --- | 
|  <pre>final DescribeInstancesRequest request = new DescribeInstancesRequest()<br />        .withInstanceIds(instanceIdsCopy);</pre>  |  <pre>final DescribeInstancesRequest request = DescribeInstancesRequest.builder()<br />        .instanceIds(instanceIdsCopy)<br />        .build();</pre>  | 

#### d. 將 v1 `*Result`回應物件取代為 v2 對`*Response`等項目
<a name="migration-example-step5-substep4"></a>

v1 和 v2 之間的一致差異是 [v2 中的所有回應物件都以 結尾，`*Response`而不是 `*Result`](migration-whats-different.md#model-classname-changes)。將 v1 `DescribeInstancesResult`匯入取代為 v2 匯入，`DescribeInstancesResponse`。

#### d. 進行 API 變更
<a name="migration-example-step5-substep5"></a>

下列陳述式需要一些變更。

```
request.setNextToken(result.getNextToken());
```

在 v2 中，[設定程式方法](migration-whats-different.md#setter-getter-methods)不使用 `set`或 搭配 `prefix`。字首`get`為 的 Getter 方法也會出現在適用於 Java 的 SDK 2.x 中

`request` 執行個體等模型類別在 v2 中是不可變的，因此我們需要使用`DescribeInstancesRequest`建置器建立新的 。

在 v2 中， 陳述式會變成以下內容。

```
request = DescribeInstancesRequest.builder()
        .nextToken(result.nextToken())
        .build();
```

#### d. 重複此動作，直到方法編譯為 v2 類別
<a name="migration-example-step5-substep6"></a>

繼續執行其餘的程式碼。將 v1 匯入取代為 v2 匯入並修正編譯錯誤。如有需要，請參閱 [v2 API 參考](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/package-summary.html)和[什麼是不同的參考](migration-whats-different.md)。

遷移此單一方法後，我們有下列 v2 程式碼。

```
import com.amazonaws.ClientConfiguration;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.RegionUtils;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.AmazonEC2Exception;
import com.amazonaws.services.ec2.model.CreateTagsRequest;
import com.amazonaws.services.ec2.model.InstanceStateName;
import com.amazonaws.services.ec2.model.Tag;
import com.amazonaws.services.ec2.model.TerminateInstancesRequest;

import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
import software.amazon.awssdk.services.ec2.model.Instance;
import software.amazon.awssdk.services.ec2.model.Reservation;
...
private static List<Instance> getRunningInstances(Ec2Client ec2, List<String> instanceIds) {
    List<Instance> runningInstances = new ArrayList<>();
        try {
            DescribeInstancesRequest request = DescribeInstancesRequest.builder()
                    .instanceIds(instanceIds)
                    .build();
            DescribeInstancesResponse result;
            do {
                // DescribeInstancesResponse is a paginated response, so use tokens with multiple re
                result = ec2.describeInstances(request);
                request = DescribeInstancesRequest.builder()   // Prepare request for next page.
                        .nextToken(result.nextToken())
                        .build();
                for (final Reservation r : result.reservations()) {
                    for (final Instance instance : r.instances()) {
                        // if instance is in a running state, add it to runningInstances list.
                        if (RUNNING_STATES.contains(instance.state().nameAsString())) {
                            runningInstances.add(instance);
                        }
                    }
                }
            } while (result.nextToken() != null);
        } catch (final Ec2Exception exception) {
            // if instance isn't found, assume its terminated and continue.
            if (exception.awsErrorDetails().errorCode().equals(NOT_FOUND_ERROR_CODE)) {
                    LOGGER.info("Instance probably terminated; moving on.");
            } else {
                throw exception;
            }
        }
        return runningInstances;
    }
...
```

由於我們正在以八種方法遷移 Java 檔案中的單一方法，因此在處理檔案時，我們會混合使用 v1 和 v2 匯入。我們在執行步驟時新增了最後六個匯入陳述式。

遷移所有程式碼後，將不再有 v1 匯入陳述式。

### 6. 從 POM 移除 v1 Maven 相依性，並從檔案移除 v1 匯入
<a name="migration-steps-example-step6"></a>

遷移 檔案中的所有 v1 程式碼後，我們會有下列 v2 SDK 匯入陳述式。

```
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.regions.ServiceMetadata;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.CreateTagsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
import software.amazon.awssdk.services.ec2.model.Instance;
import software.amazon.awssdk.services.ec2.model.InstanceStateName;
import software.amazon.awssdk.services.ec2.model.Reservation;
import software.amazon.awssdk.services.ec2.model.Tag;
import software.amazon.awssdk.services.ec2.model.TerminateInstancesRequest;
```

遷移應用程式*中的所有*檔案後，我們不再需要 POM 檔案中的 v1 相依性。如果使用 和所有 v1 相依性區塊，請從 `dependencyManagement`區段移除 v1 BOM。

### 7. 重構程式碼以使用 v2 API 增強功能
<a name="migration-steps-example-step7"></a>

對於我們遷移的程式碼片段，我們可以選擇性地使用 v2 分頁程式，並讓 SDK 管理更多資料的字符型請求。

我們可以將整個 `do` 子句取代為以下內容。

```
                DescribeInstancesIterable responses = ec2.describeInstancesPaginator(request);

                responses.reservations().stream()
                        .forEach(reservation -> reservation.instances()
                                .forEach(instance -> {
                                    if (RUNNING_STATES.contains(instance.state().nameAsString())) {
                                        runningInstances.put(instance.instanceId(), instance);
                                    }
                                }));
```

## Maven artifactId 映射的套件名稱
<a name="migration-serviceid-artifactid-mapping"></a>

當您將 Maven 或 Gradle 專案從適用於 Java 的 SDK v1 遷移至 v2 時，您需要找出要新增至建置檔案的相依性。[遷移step-by-step說明與範例](#migration-steps) （步驟 3) 中所述的方法使用匯入陳述式中的套件名稱做為起點，以決定要新增至建置檔案的相依性 （做為 artifactIds)。

您可以使用本主題中的資訊，將 v1 套件名稱對應至 v2 artifactIds。

### 套件名稱和 Maven artifactIds 中使用的常見命名慣例
<a name="migration-naming-convention"></a>

下表顯示 SDKs用於指定 SERVICE\$1ID 的常見命名慣例。SERVICE\$1ID 是 的唯一識別符 AWS 服務。例如，Amazon S3 服務的 SERVICE\$1ID 是 `s3`，而 `cognitoidentity` 是 Amazon Cognito Identity 的 SERVICE\$1ID。


| v1 套件名稱 （匯入陳述式） | v1 artifactId | v2 artifactId | v2 套件名稱 （匯入陳述式） | 
| --- | --- | --- | --- | 
| com.amazonaws.services.SERVICE\$1ID | aws-java-sdk-SERVICE\$1ID | SERVICE\$1ID | software.amazon.awssdk.services.SERVICE\$1ID | 
|   | 
| Amazon Cognito Identity (SERVICE\$1ID：cognitoidentity) 的範例 | 
| com.amazonaws.services.cognitoidentity | aws-java-sdk-cognitoidentity | cognitoidentity | software.amazon.awssdk.services.cognitoidentity | 

### SERVICE\$1ID 差異
<a name="migration-serviceid-diffs"></a>

#### 在 v1 內
<a name="migration-serviceid-diffs-withinv1"></a>

在某些情況下，相同服務的套件名稱和 artifactId 中的 SERVICE\$1ID 會有所不同。例如，下表的 CloudWatch Metrics 資料列顯示 `metrics`是套件名稱中的 SERVICE\$1ID，但 `cloudwatchmetrics`是 artifactId 的 SERVICE\$1ID。

#### 在 v2 內
<a name="migration-serviceid-diffs-withinv2"></a>

套件名稱和 artifactIds 中使用的 SERVICE\$1ID 沒有差異。

#### 在 v1 和 v2 之間
<a name="migration-serviceid-diffs-btwv1v2"></a>

對於大多數服務，v2 中的 SERVICE\$1ID 與套件名稱和 artifactIds 中的 v1 的 SERVICE\$1ID 相同。其中一個範例是 `cognitoedentity` SERVICE\$1ID，如上表所示。不過，某些 SERVICE\$1IDs會因 SDKs 而有所不同，如下表所示。

任一 v1 資料欄中的**粗體 SERVICE\$1ID** 表示它與 v2 中使用的 SERVICE\$1ID 不同。


| 服務名稱 | v1 套件名稱 | v1 artifactId | v2 artifactId | v2 套件名稱 | 
| --- | --- | --- | --- | --- | 
|  |  所有套件名稱都以 開頭`com.amazonaws.services`，如第一列所示。  |  所有 artifactIds都包含在標籤中，如第一列所示。  |  所有 artifactIds都包含在標籤中，如第一列所示。  |  所有套件名稱都以 開頭`software.amazon.awssdk`，如第一列所示。  | 
|  | 
| API Gateway | com.amazonaws.services.apigateway | <artifactId>aws-java-sdk-api-gateway</artifactId> | <artifactId>apigateway</artifactId> | software.amazon.awssdk.services.apigateway | 
| 應用程式登錄檔 | appregistry | appregistry | servicecatalogappregistry | servicecatalogappregistry | 
| Application Discovery | applicationdiscovery | 探索 | applicationdiscovery | applicationdiscovery | 
| 增強版 AI 執行期 | augmentedairuntime | augmentedairuntime | sagemakera2iruntime | sagemakera2iruntime | 
| Certificate Manager | certificatemanager | acm | acm | acm | 
| CloudControl API | cloudcontrolapi | cloudcontrolapi | cloudcontrol | cloudcontrol | 
| CloudSearch | cloudsearchv2 | cloudsearch | cloudsearch | cloudsearch | 
| CloudSearch 網域 | cloudsearchdomain | cloudsearch | cloudsearchdomain | cloudsearchdomain | 
| CloudWatch Events | cloudwatchevents | 事件 | cloudwatchevents | cloudwatchevents | 
| CloudWatch Evidently | cloudwatch 顯而易見 | cloudwatch 明顯地 | evidently | evidently | 
| CloudWatch Logs | logs | logs | cloudwatchlogs | cloudwatchlogs | 
| CloudWatch Metrics | 指標 | cloudwatchmetrics | cloudwatch | cloudwatch | 
| CloudWatch Rum | cloudwatchrum | cloudwatchrum | rum | rum | 
| Cognito 身分提供者 | cognitoidp | cognitoidp | cognitoidentityprovider | cognitoidentityprovider | 
| Connect 行銷活動 | connectcampaign | connectcampaign | 連線行銷活動 | 連線行銷活動 | 
| Connect Wisdom | connectwisdom | connectwisdom | wisdom | wisdom | 
| 資料庫遷移服務 | databasemigrationservice | dms | 資料庫遷移 | 資料庫遷移 | 
| DataZone | 資料區域 | datazoneexternal | 資料區域 | 資料區域 | 
| DynamoDB | dynamodbv2 | dynamodb | dynamodb | dynamodb | 
| 彈性檔案系統 | elasticfile 系統 | efs | efs | efs | 
| 彈性映射減少 | elasticmapreduce | emr | emr | emr | 
| Glue DataBrew | gluedatabrew | gluedatabrew | databrew | databrew | 
| IAM Roles Anywhere | iamrolesanywhere | iamrolesanywhere | rolesanywhere | rolesanywhere | 
| 身分管理 | 身分管理 | iam | iam | iam | 
| IoT 資料 | iotdata | iot | iotdataplane | iotdataplane | 
| Kinesis Analytics | kinesisanalytics | kinesis | kinesisanalytics | kinesisanalytics | 
| Kinesis Firehose | kinesisfirehose | kinesis | firehose | firehose | 
| Kinesis Video Signaling 頻道 | kinesisvideosignaling 頻道 | kinesisvideosignaling 頻道 | kinesisvideosignaling | kinesisvideosignaling | 
| Lex | lexruntime | lex | lexruntime | lexruntime | 
| 注視視覺 | lookoutforvision | lookoutforvision | lookoutvision | lookoutvision | 
| 大型主機現代化 | 大型主機模式 | 大型主機模式 | m2 | m2 | 
| Marketplace 計量 | 市場計量 | Marketplacemeteringservice | 市場計量 | 市場計量 | 
| 受管 Grafana | 受管格拉法納 | 受管格拉法納 | grafana | grafana | 
| 機械 Turk | 泥濘 | Mechanicalturkrequester | 泥濘 | 泥濘 | 
| Migration Hub 策略建議 | migrationhubstrategyrecommendations | migrationhubstrategyrecommendations | migrationhubstrategy | migrationhubstrategy | 
| Nimble Studio | nimblestudio | nimblestudio | nimble | nimble | 
| 私有 5G | private5g | private5g | 私有網路 | 私有網路 | 
| Prometheus | prometheus | prometheus | amp | amp | 
| 資源回收筒 | 資源回收筒 | 資源回收筒 | rbin | rbin | 
| Redshift 資料 API | redshiftdataapi | redshiftdataapi | redshiftdata | redshiftdata | 
| Route 53 | route53網域 | route53 | route53網域 | route53網域 | 
| Sage Maker Edge Manager | sagemakeredgemanager | sagemakeredgemanager | sagemakeredge | sagemakeredge | 
| 安全字符 | securitytoken | sts | sts | sts | 
| 伺服器遷移 | 伺服器遷移 | 伺服器遷移 | sms | sms | 
| 簡易電子郵件 | simpleemail | ses | ses | ses | 
| 簡易電子郵件 V2 | simpleemailv2 | sesv2 | sesv2 | sesv2 | 
| 簡易系統管理 | Simplesystems 管理 | ssm | ssm | ssm | 
| 簡單工作流程 | Simpleworkflow | Simpleworkflow | swf | swf | 
| 步驟函數 | 步驟函數 | 步驟函數 | sfn | sfn | 

# 適用於 Java 的 AWS SDK 1.x 和 2.x 之間的差異
<a name="migration-whats-different"></a>

本節說明將應用程式從 1.x 適用於 Java 的 AWS SDK 版轉換為 2.x 版時要注意的主要變更。

## 套件名稱變更
<a name="mig-diff-package-name-change"></a>

從適用於 Java 的 SDK 1.x 到適用於 Java 的 SDK 2.x 的明顯變更是套件名稱變更。套件名稱在 SDK 2.x `software.amazon.awssdk`中以 開頭，而 SDK 1.x 使用 。 `com.amazonaws`

這些相同名稱區分 Maven 成品，從 SDK 1.x 到 SDK 2.x。SDK 2.x 的 Maven 成品使用 `software.amazon.awssdk` groupId，而 SDK 1.x 使用 `com.amazonaws` groupId。

有些時候，您的程式碼需要對專案的`com.amazonaws`相依性，否則只會使用 SDK 2.x 成品。其中一個範例是當您使用伺服器端時 AWS Lambda。這在本指南稍早的設定 [Apache Maven 專案](setup-project-maven.md#modules-dependencies)區段中顯示。

**注意**  
SDK 1.x 中的數個套件名稱包含 。 `v2``v2` 在此情況下，使用 通常表示套件中的程式碼目標為使用第 2 版的服務。  
由於完整套件名稱以 開頭`com.amazonaws`，因此這些是 SDK 1.x 元件。SDK 1.x 中的這些套件名稱範例如下：  
`com.amazonaws.services.dynamodbv2`
`com.amazonaws.retry.v2`
`com.amazonaws.services.apigatewayv2`
`com.amazonaws.services.simpleemailv2`

## 將 2.x 版新增至您的專案
<a name="adding-v2"></a>

Maven 是使用 適用於 Java 的 AWS SDK 2.x 時管理相依性的建議方法。若要將 2.x 版元件新增至您的專案，請使用 SDK 的相依性更新您的 `pom.xml` 檔案。

**Example**  

```
<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>

<dependencies>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>dynamodb</artifactId>
    </dependency>
</dependencies>
```

您也可以[在將專案遷移至 2.x 版時side-by-side 1.x 版和](migration-side-by-side.md) 2.x 版。

## 不可變 POJO
<a name="immutable-classes"></a>

用戶端和操作要求和回應物件現在不可變，且不可在建立後變更。若要重複使用要求或回應變數，您必須建立新物件，以指派給該要求或回應變數。

**Example 1.x 中更新要求物件的**  

```
DescribeAlarmsRequest request = new DescribeAlarmsRequest();
DescribeAlarmsResult response = cw.describeAlarms(request);

request.setNextToken(response.getNextToken());
```

**Example 2.x 中更新要求物件**  

```
DescribeAlarmsRequest request = DescribeAlarmsRequest.builder().build();
DescribeAlarmsResponse response = cw.describeAlarms(request);

request = DescribeAlarmsRequest.builder()
        .nextToken(response.nextToken())
        .build();
```

## 設定程式和取得程式方法
<a name="setter-getter-methods"></a>

在 適用於 Java 的 AWS SDK 2.x 中，設定程式方法名稱不包含 `set`或 `with`字首。例如， 現在`*.withEndpoint()`是 `*.endpoint()`。

Getter 方法名稱不使用 `get`字首。

**Example 在 1.x 中使用設定器方法的**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
        		.withRegion("us-east-1")
        		.build();
```

**Example 在 2.x 中使用設定器方法的**  

```
DynamoDbClient client = DynamoDbClient.builder()
        		.region(Region.US_EAST_1)
        		.build();
```

**Example 在 1.x 中使用 getter 方法的**  

```
String token = request.getNextToken();
```

**Example 在 2.x 中使用 getter 方法的**  

```
String token = request.nextToken();
```

## 模型類別名稱
<a name="model-classname-changes"></a>

代表服務回應的模型類別名稱以 v2 `Response` 結尾，而不是 v1 `Result` 使用。

**Example 代表 v1 中回應的類別名稱**  

```
CreateApiKeyResult
AllocateAddressResult
```

**Example 代表 v2 中回應的類別名稱**  

```
CreateApiKeyResponse
AllocateAddressResponse
```

## 程式庫和公用程式的遷移狀態
<a name="migration-libraries-utilities"></a>

### 適用於 Java 的 SDK 程式庫和公用程式
<a name="migration-java-sdk-libs-utils"></a>

下表列出適用於 Java 的 SDK 程式庫和公用程式的遷移狀態。


| 1.12.x 版名稱 | 2.x 版名稱 | 自 2.x 版本以來 | 
| --- | --- | --- | 
| DynamoDBMapper | [DynamoDbEnhancedClient](dynamodb-enhanced-client.md) | 2.12.0 | 
| 等待程式 | [等待程式](waiters.md) | 2.15.0 | 
| CloudFrontUrlSigner、CloudFrontCookieSigner | [CloudFrontUtilities](https://aws.amazon.com/blogs/developer/amazon-cloudfront-signed-urls-and-cookies-are-now-supported-in-aws-sdk-for-java-2-x/) | 2.18.33 | 
| TransferManager | [S3TransferManager](transfer-manager.md) | 2.19.0 | 
| EC2 中繼資料用戶端 |  [EC2 中繼資料用戶端](examples-ec2-IMDS.md)  | 2.19.29 | 
| S3 URI 剖析器 |  [S3 URI 剖析器](https://aws.amazon.com/blogs/devops/s3-uri-parsing-is-now-available-in-aws-sdk-for-java-2-x/)  | 2.20.41 | 
| IAM 政策建置器 | [IAM 政策建置器](feature-iam-policy-builder.md) | 2.20.126 | 
| S3 事件通知 | [S3 事件通知](examples-s3-event-notifications.md#s3-event-notification-read) | 2.25.11  | 
| Amazon SQS 用戶端緩衝 | [Amazon SQS 的自動請求批次處理 API](sqs-auto-batch.md) | 2.28.0 | 
| Progress Listeners | Progress Listeners | [尚未發佈](https://github.com/aws/aws-sdk-java-v2/issues/25) | 

### 相關程式庫
<a name="migration-other-sdks"></a>

下表列出個別發行但使用適用於 Java 的 SDK 2.x 的程式庫。


| 與適用於 Java 的 開發套件 2.x 版搭配使用的名稱 | 自版本 | 
| --- | --- | 
|  [Amazon S3 加密用戶端](https://docs.aws.amazon.com/amazon-s3-encryption-client/latest/developerguide/what-is-s3-encryption-client.html)  |  3.0.01  | 
| [AWS 適用於 DynamoDB 的資料庫加密 SDK](https://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/ddb-java.html) | 3.0.02 | 

#### 1Amazon S3 加密用戶端
<a name="migration-s3-encryption-sdk"></a>

您可以使用下列 Maven 相依性來取得 Amazon S3 的加密用戶端。

```
<dependency>
    <groupId>software.amazon.encryption.s3</groupId>
    <artifactId>amazon-s3-encryption-client-java</artifactId>
    <version>3.x</version>
</dependency>
```

#### 2AWS 適用於 DynamoDB 的資料庫加密 SDK
<a name="migration-ddb-encryption-sdk"></a>

適用於 DynamoDB 的 AWS 資料庫加密 SDK 可用於 V2，方法是使用下列 Maven 相依性。

```
<dependency> 
    <groupId>software.amazon.cryptography</groupId>
    <artifactId>aws-database-encryption-sdk-dynamodb</artifactId>
    <version>3.x</version>
</dependency>
```

與 Java 開發套件 v1 搭配使用的 DynamoDB 加密程式庫相關資訊，請參閱 [AWS Database Encryption SDK 開發人員指南](https://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/java.html) （名為 *Amazon DynamoDB Encryption Client for Java*) 和 [GitHub](https://github.com/aws/aws-dynamodb-encryption-java)。

如需與 Java 開發套件 V2 相容之 DynamoDB 加密程式庫的詳細資訊，請參閱[AWS 資料庫加密開發套件開發人員指南](https://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/ddb-java.html)和 [GitHub 來源](https://github.com/aws/aws-database-encryption-sdk-dynamodb)。

如需有關加密程式庫的遷移資訊，請參閱 [AWS Database Encryption SDK 開發人員指南](https://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/ddb-java-migrate.html)。

### 程式庫和公用程式的遷移詳細資訊
<a name="migrate-libs-utils-details"></a>
+ [Transfer Manager](migration-s3-transfer-manager.md)
+ [EC2 中繼資料公用程式](migration-imds.md)
+ [CloudFront 預先簽署](migration-cloudfront-presigning.md)
+ [S3 URI 剖析](migration-s3-uri-parser.md)
+ [DynamoDB 映射/文件 APIs](migration-ddb-mapper.md) 
+ [IAM 政策建置器](migration-iam-policy-builder.md)
+ [S3 事件通知](migration-s3-event-notification.md)
+ SDK 指標發佈 ([1.x 文件](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/generating-sdk-metrics.html)、[2.x 文件](metrics.md))

# 用戶端變更
<a name="migration-clients"></a>

## 用戶端建置器
<a name="client-builder"></a>

您必須使用用戶端建置器方法建立所有用戶端。建構子已無法使用。

**Example 在 1.x 版中建立用戶端**  

```
AmazonDynamoDB ddbClient = AmazonDynamoDBClientBuilder.defaultClient();
AmazonDynamoDBClient ddbClient = new AmazonDynamoDBClient();
```

**Example 在 2.x 版中建立用戶端**  

```
DynamoDbClient ddbClient = DynamoDbClient.create();
DynamoDbClient ddbClient = DynamoDbClient.builder().build();
```

## 用戶端類別名稱
<a name="class-names"></a>

所有用戶端類別名稱現在都完全採用駝色大小寫，不再以 為字首`Amazon`。這些變更會符合 AWS CLI中使用的名稱。

**Example 在 1.x 中類別名稱的**  

```
AmazonDynamoDB
AWSACMPCAAsyncClient
```

**Example 在 2.x 中的類別名稱**  

```
DynamoDbClient
AcmAsyncClient
```


**用戶端類別名稱變更**  

| 1.x 用戶端 | 2.x 用戶端 | 
| --- | --- | 
| com.amazonaws.services.acmpca.AWSACMPCAAsyncClient | software.amazon.awssdk.services.acm.AcmAsyncClient | 
| com.amazonaws.services.acmpca.AWSACMPCAClient | software.amazon.awssdk.services.acm.AcmClient | 
| com.amazonaws.services.alexaforbusiness.AmazonAlexaForBusinessAsyncClient | software.amazon.awssdk.services.alexaforbusiness.AlexaForBusinessAsyncClient | 
| com.amazonaws.services.alexaforbusiness.AmazonAlexaForBusinessClient | software.amazon.awssdk.services.alexaforbusiness.AlexaForBusinessClient | 
| com.amazonaws.services.apigateway.AmazonApiGatewayAsyncClient | software.amazon.awssdk.services.apigateway.ApiGatewayAsyncClient | 
| com.amazonaws.services.apigateway.AmazonApiGatewayClient | software.amazon.awssdk.services.apigateway.ApiGatewayClient | 
| com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScalingAsyncClient | software.amazon.awssdk.services.applicationautoscaling.ApplicationAutoScalingAsyncClient | 
| com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScalingClient | software.amazon.awssdk.services.applicationautoscaling.ApplicationAutoScalingClient | 
| com.amazonaws.services.applicationdiscovery.AWSApplicationDiscoveryAsyncClient | software.amazon.awssdk.services.applicationdiscovery.ApplicationDiscoveryAsyncClient | 
| com.amazonaws.services.applicationdiscovery.AWSApplicationDiscoveryClient | software.amazon.awssdk.services.applicationdiscovery.ApplicationDiscoveryClient | 
| com.amazonaws.services.appstream.AmazonAppStreamAsyncClient | software.amazon.awssdk.services.appstream.AppStreamAsyncClient | 
| com.amazonaws.services.appstream.AmazonAppStreamClient | software.amazon.awssdk.services.appstream.AppStreamClient | 
| com.amazonaws.services.appsync.AWSAppSyncAsyncClient | software.amazon.awssdk.services.appsync.AppSyncAsyncClient | 
| com.amazonaws.services.appsync.AWSAppSyncClient | software.amazon.awssdk.services.appsync.AppSyncClient | 
| com.amazonaws.services.athena.AmazonAthenaAsyncClient | software.amazon.awssdk.services.athena.AthenaAsyncClient | 
| com.amazonaws.services.athena.AmazonAthenaClient | software.amazon.awssdk.services.athena.AthenaClient | 
| com.amazonaws.services.autoscaling.AmazonAutoScalingAsyncClient | software.amazon.awssdk.services.autoscaling.AutoScalingAsyncClient | 
| com.amazonaws.services.autoscaling.AmazonAutoScalingClient | software.amazon.awssdk.services.autoscaling.AutoScalingClient | 
| com.amazonaws.services.autoscalingplans.AWSAutoScalingPlansAsyncClient | software.amazon.awssdk.services.autoscalingplans.AutoScalingPlansAsyncClient | 
| com.amazonaws.services.autoscalingplans.AWSAutoScalingPlansClient | software.amazon.awssdk.services.autoscalingplans.AutoScalingPlansClient | 
| com.amazonaws.services.batch.AWSBatchAsyncClient | software.amazon.awssdk.services.batch.BatchAsyncClient | 
| com.amazonaws.services.batch.AWSBatchClient | software.amazon.awssdk.services.batch.BatchClient | 
| com.amazonaws.services.budgets.AWSBudgetsAsyncClient | software.amazon.awssdk.services.budgets.BudgetsAsyncClient | 
| com.amazonaws.services.budgets.AWSBudgetsClient | software.amazon.awssdk.services.budgets.BudgetsClient | 
| com.amazonaws.services.certificatemanager.AWSCertificateManagerAsyncClient | software.amazon.awssdk.services.acm.AcmAsyncClient | 
| com.amazonaws.services.certificatemanager.AWSCertificateManagerClient | software.amazon.awssdk.services.acm.AcmClient | 
| com.amazonaws.services.cloud9.AWSCloud9AsyncClient | software.amazon.awssdk.services.cloud9.Cloud9AsyncClient | 
| com.amazonaws.services.cloud9.AWSCloud9Client | software.amazon.awssdk.services.cloud9.Cloud9Client | 
| com.amazonaws.services.clouddirectory.AmazonCloudDirectoryAsyncClient | software.amazon.awssdk.services.clouddirectory.CloudDirectoryAsyncClient | 
| com.amazonaws.services.clouddirectory.AmazonCloudDirectoryClient | software.amazon.awssdk.services.clouddirectory.CloudDirectoryClient | 
| com.amazonaws.services.cloudformation.AmazonCloudFormationAsyncClient | software.amazon.awssdk.services.cloudformation.CloudFormationAsyncClient | 
| com.amazonaws.services.cloudformation.AmazonCloudFormationClient | software.amazon.awssdk.services.cloudformation.CloudFormationClient | 
| com.amazonaws.services.cloudfront.AmazonCloudFrontAsyncClient | software.amazon.awssdk.services.cloudfront.CloudFrontAsyncClient | 
| com.amazonaws.services.cloudfront.AmazonCloudFrontClient | software.amazon.awssdk.services.cloudfront.CloudFrontClient | 
| com.amazonaws.services.cloudhsm.AWSCloudHSMAsyncClient | software.amazon.awssdk.services.cloudhsm.CloudHsmAsyncClient | 
| com.amazonaws.services.cloudhsm.AWSCloudHSMClient | software.amazon.awssdk.services.cloudhsm.CloudHsmClient | 
| com.amazonaws.services.cloudhsmv2.AWSCloudHSMV2AsyncClient | software.amazon.awssdk.services.cloudhsmv2.CloudHsmV2AsyncClient | 
| com.amazonaws.services.cloudhsmv2.AWSCloudHSMV2Client | software.amazon.awssdk.services.cloudhsmv2.CloudHsmV2Client | 
| com.amazonaws.services.cloudsearchdomain.AmazonCloudSearchDomainAsyncClient | software.amazon.awssdk.services.cloudsearchdomain.CloudSearchDomainAsyncClient | 
| com.amazonaws.services.cloudsearchdomain.AmazonCloudSearchDomainClient | software.amazon.awssdk.services.cloudsearchdomain.CloudSearchDomainClient | 
| com.amazonaws.services.cloudsearchv2.AmazonCloudSearchAsyncClient | software.amazon.awssdk.services.cloudsearch.CloudSearchAsyncClient | 
| com.amazonaws.services.cloudsearchv2.AmazonCloudSearchClient | software.amazon.awssdk.services.cloudsearch.CloudSearchClient | 
| com.amazonaws.services.cloudtrail.AWSCloudTrailAsyncClient | software.amazon.awssdk.services.cloudtrail.CloudTrailAsyncClient | 
| com.amazonaws.services.cloudtrail.AWSCloudTrailClient | software.amazon.awssdk.services.cloudtrail.CloudTrailClient | 
| com.amazonaws.services.cloudwatch.AmazonCloudWatchAsyncClient | software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient | 
| com.amazonaws.services.cloudwatch.AmazonCloudWatchClient | software.amazon.awssdk.services.cloudwatch.CloudWatchClient | 
| com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEventsAsyncClient | software.amazon.awssdk.services.cloudwatchevents.CloudWatchEventsAsyncClient | 
| com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEventsClient | software.amazon.awssdk.services.cloudwatchevents.CloudWatchEventsClient | 
| com.amazonaws.services.codebuild.AWSCodeBuildAsyncClient | software.amazon.awssdk.services.codebuild.CodeBuildAsyncClient | 
| com.amazonaws.services.codebuild.AWSCodeBuildClient | software.amazon.awssdk.services.codebuild.CodeBuildClient | 
| com.amazonaws.services.codecommit.AWSCodeCommitAsyncClient | software.amazon.awssdk.services.codecommit.CodeCommitAsyncClient | 
| com.amazonaws.services.codecommit.AWSCodeCommitClient | software.amazon.awssdk.services.codecommit.CodeCommitClient | 
| com.amazonaws.services.codedeploy.AmazonCodeDeployAsyncClient | software.amazon.awssdk.services.codedeploy.CodeDeployAsyncClient | 
| com.amazonaws.services.codedeploy.AmazonCodeDeployClient | software.amazon.awssdk.services.codedeploy.CodeDeployClient | 
| com.amazonaws.services.codepipeline.AWSCodePipelineAsyncClient | software.amazon.awssdk.services.codepipeline.CodePipelineAsyncClient | 
| com.amazonaws.services.codepipeline.AWSCodePipelineClient | software.amazon.awssdk.services.codepipeline.CodePipelineClient | 
| com.amazonaws.services.codestar.AWSCodeStarAsyncClient | software.amazon.awssdk.services.codestar.CodeStarAsyncClient | 
| com.amazonaws.services.codestar.AWSCodeStarClient | software.amazon.awssdk.services.codestar.CodeStarClient | 
| com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityAsyncClient | software.amazon.awssdk.services.cognitoidentity.CognitoIdentityAsyncClient | 
| com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient | software.amazon.awssdk.services.cognitoidentity.CognitoIdentityClient | 
| com.amazonaws.services.cognitoidp.AWSCognitoIdentityProviderAsyncClient | software.amazon.awssdk.services.cognitoidentityprovider.CognitoIdentityProviderAsyncClient | 
| com.amazonaws.services.cognitoidp.AWSCognitoIdentityProviderClient | software.amazon.awssdk.services.cognitoidentityprovider.CognitoIdentityProviderClient | 
| com.amazonaws.services.cognitosync.AmazonCognitoSyncAsyncClient | software.amazon.awssdk.services.cognitosync.CognitoSyncAsyncClient | 
| com.amazonaws.services.cognitosync.AmazonCognitoSyncClient | software.amazon.awssdk.services.cognitosync.CognitoSyncClient | 
| com.amazonaws.services.comprehend.AmazonComprehendAsyncClient | software.amazon.awssdk.services.comprehend.ComprehendAsyncClient | 
| com.amazonaws.services.comprehend.AmazonComprehendClient | software.amazon.awssdk.services.comprehend.ComprehendClient | 
| com.amazonaws.services.config.AmazonConfigAsyncClient | software.amazon.awssdk.services.config.ConfigAsyncClient | 
| com.amazonaws.services.config.AmazonConfigClient | software.amazon.awssdk.services.config.ConfigClient | 
| com.amazonaws.services.connect.AmazonConnectAsyncClient | software.amazon.awssdk.services.connect.ConnectAsyncClient | 
| com.amazonaws.services.connect.AmazonConnectClient | software.amazon.awssdk.services.connect.ConnectClient | 
| com.amazonaws.services.costandusagereport.AWSCostAndUsageReportAsyncClient | software.amazon.awssdk.services.costandusagereport.CostAndUsageReportAsyncClient | 
| com.amazonaws.services.costandusagereport.AWSCostAndUsageReportClient | software.amazon.awssdk.services.costandusagereport.CostAndUsageReportClient | 
| com.amazonaws.services.costexplorer.AWSCostExplorerAsyncClient | software.amazon.awssdk.services.costexplorer.CostExplorerAsyncClient | 
| com.amazonaws.services.costexplorer.AWSCostExplorerClient | software.amazon.awssdk.services.costexplorer.CostExplorerClient | 
| com.amazonaws.services.databasemigrationservice.AWSDatabaseMigrationServiceAsyncClient | software.amazon.awssdk.services.databasemigration.DatabaseMigrationAsyncClient | 
| com.amazonaws.services.databasemigrationservice.AWSDatabaseMigrationServiceClient | software.amazon.awssdk.services.databasemigration.DatabaseMigrationClient | 
| com.amazonaws.services.datapipeline.DataPipelineAsyncClient | software.amazon.awssdk.services.datapipeline.DataPipelineAsyncClient | 
| com.amazonaws.services.datapipeline.DataPipelineClient | software.amazon.awssdk.services.datapipeline.DataPipelineAsyncClient | 
| com.amazonaws.services.dax.AmazonDaxAsyncClient | software.amazon.awssdk.services.dax.DaxAsyncClient | 
| com.amazonaws.services.dax.AmazonDaxClient | software.amazon.awssdk.services.dax.DaxClient | 
| com.amazonaws.services.devicefarm.AWSDeviceFarmAsyncClient | software.amazon.awssdk.services.devicefarm.DeviceFarmAsyncClient | 
| com.amazonaws.services.devicefarm.AWSDeviceFarmClient | software.amazon.awssdk.services.devicefarm.DeviceFarmClient | 
| com.amazonaws.services.directconnect.AmazonDirectConnectAsyncClient | software.amazon.awssdk.services.directconnect.DirectConnectAsyncClient | 
| com.amazonaws.services.directconnect.AmazonDirectConnectClient | software.amazon.awssdk.services.directconnect.DirectConnectClient | 
| com.amazonaws.services.directory.AWSDirectoryServiceAsyncClient | software.amazon.awssdk.services.directory.DirectoryAsyncClient | 
| com.amazonaws.services.directory.AWSDirectoryServiceClient | software.amazon.awssdk.services.directory.DirectoryClient | 
| com.amazonaws.services.dlm.AmazonDLMAsyncClient | software.amazon.awssdk.services.dlm.DlmAsyncClient | 
| com.amazonaws.services.dlm.AmazonDLMClient | software.amazon.awssdk.services.dlm.DlmClient | 
| com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsyncClient | software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient | 
| com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient | software.amazon.awssdk.services.dynamodb.DynamoDbClient | 
| com.amazonaws.services.dynamodbv2.AmazonDynamoDBStreamsAsyncClient | software.amazon.awssdk.services.dynamodb.streams.DynamoDbStreamsAsyncClient | 
| com.amazonaws.services.dynamodbv2.AmazonDynamoDBStreamsClient | software.amazon.awssdk.services.dynamodb.streams.DynamoDbStreamsClient | 
| com.amazonaws.services.ec2.AmazonEC2AsyncClient | software.amazon.awssdk.services.ec2.Ec2AsyncClient | 
| com.amazonaws.services.ec2.AmazonEC2Client | software.amazon.awssdk.services.ec2.Ec2Client | 
| com.amazonaws.services.ecr.AmazonECRAsyncClient | software.amazon.awssdk.services.ecr.EcrAsyncClient | 
| com.amazonaws.services.ecr.AmazonECRClient | software.amazon.awssdk.services.ecr.EcrClient | 
| com.amazonaws.services.ecs.AmazonECSAsyncClient | software.amazon.awssdk.services.ecs.EcsAsyncClient | 
| com.amazonaws.services.ecs.AmazonECSClient | software.amazon.awssdk.services.ecs.EcsClient | 
| com.amazonaws.services.eks.AmazonEKSAsyncClient | software.amazon.awssdk.services.eks.EksAsyncClient | 
| com.amazonaws.services.eks.AmazonEKSClient | software.amazon.awssdk.services.eks.EksClient | 
| com.amazonaws.services.elasticache.AmazonElastiCacheAsyncClient | software.amazon.awssdk.services.elasticache.ElastiCacheAsyncClient | 
| com.amazonaws.services.elasticache.AmazonElastiCacheClient | software.amazon.awssdk.services.elasticache.ElastiCacheClient | 
| com.amazonaws.services.elasticbeanstalk.AWSElasticBeanstalkAsyncClient | software.amazon.awssdk.services.elasticbeanstalk.ElasticBeanstalkAsyncClient | 
| com.amazonaws.services.elasticbeanstalk.AWSElasticBeanstalkClient | software.amazon.awssdk.services.elasticbeanstalk.ElasticBeanstalkClient | 
| com.amazonaws.services.elasticfilesystem.AmazonElasticFileSystemAsyncClient | software.amazon.awssdk.services.efs.EfsAsyncClient | 
| com.amazonaws.services.elasticfilesystem.AmazonElasticFileSystemClient | software.amazon.awssdk.services.efs.EfsClient | 
| com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingAsyncClient | software.amazon.awssdk.services.elasticloadbalancing.ElasticLoadBalancingAsyncClient | 
| com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient | software.amazon.awssdk.services.elasticloadbalancing.ElasticLoadBalancingClient | 
| com.amazonaws.services.elasticloadbalancingv2.AmazonElasticLoadBalancingAsyncClient | software.amazon.awssdk.services.elasticloadbalancingv2.ElasticLoadBalancingV2AsyncClient | 
| com.amazonaws.services.elasticloadbalancingv2.AmazonElasticLoadBalancingClient | software.amazon.awssdk.services.elasticloadbalancingv2.ElasticLoadBalancingV2Client | 
| com.amazonaws.services.elasticmapreduce.AmazonElasticMapReduceAsyncClient | software.amazon.awssdk.services.emr.EmrAsyncClient | 
| com.amazonaws.services.elasticmapreduce.AmazonElasticMapReduceClient | software.amazon.awssdk.services.emr.EmrClient | 
| com.amazonaws.services.elasticsearch.AWSElasticsearchAsyncClient | software.amazon.awssdk.services.elasticsearch.ElasticsearchAsyncClient | 
| com.amazonaws.services.elasticsearch.AWSElasticsearchClient | software.amazon.awssdk.services.elasticsearch.ElasticsearchClient | 
| com.amazonaws.services.elastictranscoder.AmazonElasticTranscoderAsyncClient | software.amazon.awssdk.services.elastictranscoder.ElasticTranscoderAsyncClient | 
| com.amazonaws.services.elastictranscoder.AmazonElasticTranscoderClient | software.amazon.awssdk.services.elastictranscoder.ElasticTranscoderClient | 
| com.amazonaws.services.fms.AWSFMSAsyncClient | software.amazon.awssdk.services.fms.FmsAsyncClient | 
| com.amazonaws.services.fms.AWSFMSClient | software.amazon.awssdk.services.fms.FmsClient | 
| com.amazonaws.services.gamelift.AmazonGameLiftAsyncClient | software.amazon.awssdk.services.gamelift.GameLiftAsyncClient | 
| com.amazonaws.services.gamelift.AmazonGameLiftClient | software.amazon.awssdk.services.gamelift.GameLiftClient | 
| com.amazonaws.services.glacier.AmazonGlacierAsyncClient | software.amazon.awssdk.services.glacier.GlacierAsyncClient | 
| com.amazonaws.services.glacier.AmazonGlacierClient | software.amazon.awssdk.services.glacier.GlacierClient | 
| com.amazonaws.services.glue.AWSGlueAsyncClient | software.amazon.awssdk.services.glue.GlueAsyncClient | 
| com.amazonaws.services.glue.AWSGlueClient | software.amazon.awssdk.services.glue.GlueClient | 
| com.amazonaws.services.greengrass.AWSGreengrassAsyncClient | software.amazon.awssdk.services.greengrass.GreengrassAsyncClient | 
| com.amazonaws.services.greengrass.AWSGreengrassClient | software.amazon.awssdk.services.greengrass.GreengrassClient | 
| com.amazonaws.services.guardduty.AmazonGuardDutyAsyncClient | software.amazon.awssdk.services.guardduty.GuardDutyAsyncClient | 
| com.amazonaws.services.guardduty.AmazonGuardDutyClient | software.amazon.awssdk.services.guardduty.GuardDutyClient | 
| com.amazonaws.services.health.AWSHealthAsyncClient | software.amazon.awssdk.services.health.HealthAsyncClient | 
| com.amazonaws.services.health.AWSHealthClient | software.amazon.awssdk.services.health.HealthClient | 
| com.amazonaws.services.identitymanagement.AmazonIdentityManagementAsyncClient | software.amazon.awssdk.services.iam.IamAsyncClient | 
| com.amazonaws.services.identitymanagement.AmazonIdentityManagementClient | software.amazon.awssdk.services.iam.IamClient | 
| com.amazonaws.services.importexport.AmazonImportExportAsyncClient | 已棄用 | 
| com.amazonaws.services.importexport.AmazonImportExportClient | 已棄用 | 
| com.amazonaws.services.inspector.AmazonInspectorAsyncClient | software.amazon.awssdk.services.inspector.InspectorAsyncClient | 
| com.amazonaws.services.inspector.AmazonInspectorClient | software.amazon.awssdk.services.inspector.InspectorClient | 
| com.amazonaws.services.iot.AWSIotAsyncClient | software.amazon.awssdk.services.iot.IotAsyncClient | 
| com.amazonaws.services.iot.AWSIotClient | software.amazon.awssdk.services.iot.IotClient | 
| com.amazonaws.services.iot1clickdevices.AWSIoT1ClickDevicesAsyncClient | software.amazon.awssdk.services.iot1clickdevices.Iot1ClickDevicesAsyncClient | 
| com.amazonaws.services.iot1clickdevices.AWSIoT1ClickDevicesClient | software.amazon.awssdk.services.iot1clickdevices.Iot1ClickDevicesClient | 
| com.amazonaws.services.iot1clickprojects.AWSIoT1ClickProjectsAsyncClient | software.amazon.awssdk.services.iot1clickprojects.Iot1ClickProjectsAsyncClient | 
| com.amazonaws.services.iot1clickprojects.AWSIoT1ClickProjectsClient | software.amazon.awssdk.services.iot1clickprojects.Iot1ClickProjectsClient | 
| com.amazonaws.services.iotanalytics.AWSIoTAnalyticsAsyncClient | software.amazon.awssdk.services.iotanalytics.IotAnalyticsAsyncClient | 
| com.amazonaws.services.iotanalytics.AWSIoTAnalyticsClient | software.amazon.awssdk.services.iotanalytics.IotAnalyticsClient | 
| com.amazonaws.services.iotdata.AWSIotDataAsyncClient | software.amazon.awssdk.services.iotdata.IotDataAsyncClient | 
| com.amazonaws.services.iotdata.AWSIotDataClient | software.amazon.awssdk.services.iotdata.IotDataClient | 
| com.amazonaws.services.iotjobsdataplane.AWSIoTJobsDataPlaneAsyncClient | software.amazon.awssdk.services.iotdataplane.IotDataPlaneAsyncClient | 
| com.amazonaws.services.iotjobsdataplane.AWSIoTJobsDataPlaneClient | software.amazon.awssdk.services.iotdataplane.IotDataPlaneClient | 
| com.amazonaws.services.kinesis.AmazonKinesisAsyncClient | software.amazon.awssdk.services.kinesis.KinesisAsyncClient | 
| com.amazonaws.services.kinesis.AmazonKinesisClient | software.amazon.awssdk.services.kinesis.KinesisClient | 
| com.amazonaws.services.kinesisanalytics.AmazonKinesisAnalyticsAsyncClient | software.amazon.awssdk.services.kinesisanalytics.KinesisAnalyticsAsyncClient | 
| com.amazonaws.services.kinesisanalytics.AmazonKinesisAnalyticsClient | software.amazon.awssdk.services.kinesisanalytics.KinesisAnalyticsClient | 
| com.amazonaws.services.kinesisfirehose.AmazonKinesisFirehoseAsyncClient | software.amazon.awssdk.services.firehose.FirehoseAsyncClient | 
| com.amazonaws.services.kinesisfirehose.AmazonKinesisFirehoseClient | software.amazon.awssdk.services.firehose.FirehoseClient | 
| com.amazonaws.services.kinesisvideo.AmazonKinesisVideoArchivedMediaAsyncClient | software.amazon.awssdk.services.kinesisvideoarchivedmedia.KinesisVideoArchivedMediaAsyncClient | 
| com.amazonaws.services.kinesisvideo.AmazonKinesisVideoArchivedMediaClient | software.amazon.awssdk.services.kinesisvideoarchivedmedia.KinesisVideoArchivedMediaClient | 
| com.amazonaws.services.kinesisvideo.AmazonKinesisVideoAsyncClient | software.amazon.awssdk.services.kinesisvideo.KinesisVideoAsyncClient | 
| com.amazonaws.services.kinesisvideo.AmazonKinesisVideoClient | software.amazon.awssdk.services.kinesisvideo.KinesisVideoClient | 
| com.amazonaws.services.kinesisvideo.AmazonKinesisVideoMediaAsyncClient | software.amazon.awssdk.services.kinesisvideomedia.KinesisVideoMediaAsyncClient | 
| com.amazonaws.services.kinesisvideo.AmazonKinesisVideoMediaClient | software.amazon.awssdk.services.kinesisvideomedia.KinesisVideoMediaClient | 
| com.amazonaws.services.kinesisvideo.AmazonKinesisVideoPutMediaClient | 不支援  | 
| com.amazonaws.services.kms.AWSKMSAsyncClient | software.amazon.awssdk.services.kms.KmsAsyncClient | 
| com.amazonaws.services.kms.AWSKMSClient | software.amazon.awssdk.services.kms.KmsClient | 
| com.amazonaws.services.lambda.AWSLambdaAsyncClient | software.amazon.awssdk.services.lambda.LambdaAsyncClient | 
| com.amazonaws.services.lambda.AWSLambdaClient | software.amazon.awssdk.services.lambda.LambdaClient | 
| com.amazonaws.services.lexmodelbuilding.AmazonLexModelBuildingAsyncClient | software.amazon.awssdk.services.lexmodelbuilding.LexModelBuildingAsyncClient | 
| com.amazonaws.services.lexmodelbuilding.AmazonLexModelBuildingClient | software.amazon.awssdk.services.lexmodelbuilding.LexModelBuildingClient | 
| com.amazonaws.services.lexruntime.AmazonLexRuntimeAsyncClient | software.amazon.awssdk.services.lexruntime.LexRuntimeAsyncClient | 
| com.amazonaws.services.lexruntime.AmazonLexRuntimeClient | software.amazon.awssdk.services.lexruntime.LexRuntimeClient | 
| com.amazonaws.services.lightsail.AmazonLightsailAsyncClient | software.amazon.awssdk.services.lightsail.LightsailAsyncClient | 
| com.amazonaws.services.lightsail.AmazonLightsailClient | software.amazon.awssdk.services.lightsail.LightsailClient | 
| com.amazonaws.services.logs.AWSLogsAsyncClient | software.amazon.awssdk.services.logs.LogsAsyncClient | 
| com.amazonaws.services.logs.AWSLogsClient | software.amazon.awssdk.services.logs.LogsClient | 
| com.amazonaws.services.machinelearning.AmazonMachineLearningAsyncClient | software.amazon.awssdk.services.machinelearning.MachineLearningAsyncClient | 
| com.amazonaws.services.machinelearning.AmazonMachineLearningClient | software.amazon.awssdk.services.machinelearning.MachineLearningClient | 
| com.amazonaws.services.macie.AmazonMacieAsyncClient | software.amazon.awssdk.services.macie.MacieAsyncClient | 
| com.amazonaws.services.macie.AmazonMacieClient | software.amazon.awssdk.services.macie.MacieClient | 
| com.amazonaws.services.marketplacecommerceanalytics.AWSMarketplaceCommerceAnalyticsAsyncClient | software.amazon.awssdk.services.marketplacecommerceanalytics.MarketplaceCommerceAnalyticsAsyncClient | 
| com.amazonaws.services.marketplacecommerceanalytics.AWSMarketplaceCommerceAnalyticsClient | software.amazon.awssdk.services.marketplacecommerceanalytics.MarketplaceCommerceAnalyticsClient | 
| com.amazonaws.services.marketplaceentitlement.AWSMarketplaceEntitlementAsyncClient | software.amazon.awssdk.services.marketplaceentitlement.MarketplaceEntitlementAsyncClient | 
| com.amazonaws.services.marketplaceentitlement.AWSMarketplaceEntitlementClient | software.amazon.awssdk.services.marketplaceentitlement.MarketplaceEntitlementClient | 
| com.amazonaws.services.marketplacemetering.AWSMarketplaceMeteringAsyncClient | software.amazon.awssdk.services.marketplacemetering.MarketplaceMeteringAsyncClient | 
| com.amazonaws.services.marketplacemetering.AWSMarketplaceMeteringClient | software.amazon.awssdk.services.marketplacemetering.MarketplaceMeteringClient | 
| com.amazonaws.services.mediaconvert.AWSMediaConvertAsyncClient | software.amazon.awssdk.services.mediaconvert.MediaConvertAsyncClient | 
| com.amazonaws.services.mediaconvert.AWSMediaConvertClient | software.amazon.awssdk.services.mediaconvert.MediaConvertClient | 
| com.amazonaws.services.medialive.AWSMediaLiveAsyncClient | software.amazon.awssdk.services.medialive.MediaLiveAsyncClient | 
| com.amazonaws.services.medialive.AWSMediaLiveClient | software.amazon.awssdk.services.medialive.MediaLiveClient | 
| com.amazonaws.services.mediapackage.AWSMediaPackageAsyncClient | software.amazon.awssdk.services.mediapackage.MediaPackageAsyncClient | 
| com.amazonaws.services.mediapackage.AWSMediaPackageClient | software.amazon.awssdk.services.mediapackage.MediaPackageClient | 
| com.amazonaws.services.mediastore.AWSMediaStoreAsyncClient | software.amazon.awssdk.services.mediastore.MediaStoreAsyncClient | 
| com.amazonaws.services.mediastore.AWSMediaStoreClient | software.amazon.awssdk.services.mediastore.MediaStoreClient | 
| com.amazonaws.services.mediastoredata.AWSMediaStoreDataAsyncClient | software.amazon.awssdk.services.mediastoredata.MediaStoreDataAsyncClient | 
| com.amazonaws.services.mediastoredata.AWSMediaStoreDataClient | software.amazon.awssdk.services.mediastoredata.MediaStoreDataClient | 
| com.amazonaws.services.mediatailor.AWSMediaTailorAsyncClient | software.amazon.awssdk.services.mediatailor.MediaTailorAsyncClient | 
| com.amazonaws.services.mediatailor.AWSMediaTailorClient | software.amazon.awssdk.services.mediatailor.MediaTailorClient | 
| com.amazonaws.services.migrationhub.AWSMigrationHubAsyncClient | software.amazon.awssdk.services.migrationhub.MigrationHubAsyncClient | 
| com.amazonaws.services.migrationhub.AWSMigrationHubClient | software.amazon.awssdk.services.migrationhub.MigrationHubClient | 
| com.amazonaws.services.mobile.AWSMobileAsyncClient | software.amazon.awssdk.services.mobile.MobileAsyncClient | 
| com.amazonaws.services.mobile.AWSMobileClient | software.amazon.awssdk.services.mobile.MobileClient | 
| com.amazonaws.services.mq.AmazonMQAsyncClient | software.amazon.awssdk.services.mq.MqAsyncClient | 
| com.amazonaws.services.mq.AmazonMQClient | software.amazon.awssdk.services.mq.MqClient | 
| com.amazonaws.services.mturk.AmazonMTurkAsyncClient | software.amazon.awssdk.services.mturk.MTurkAsyncClient | 
| com.amazonaws.services.mturk.AmazonMTurkClient | software.amazon.awssdk.services.mturk.MTurkClient | 
| com.amazonaws.services.neptune.AmazonNeptuneAsyncClient | software.amazon.awssdk.services.neptune.NeptuneAsyncClient | 
| com.amazonaws.services.neptune.AmazonNeptuneClient | software.amazon.awssdk.services.neptune.NeptuneClient | 
| com.amazonaws.services.opsworks.AWSOpsWorksAsyncClient | software.amazon.awssdk.services.opsworks.OpsWorksAsyncClient | 
| com.amazonaws.services.opsworks.AWSOpsWorksClient | software.amazon.awssdk.services.opsworks.OpsWorksClient | 
| com.amazonaws.services.opsworkscm.AWSOpsWorksCMAsyncClient | software.amazon.awssdk.services.opsworkscm.OpsWorksCmAsyncClient | 
| com.amazonaws.services.opsworkscm.AWSOpsWorksCMClient | software.amazon.awssdk.services.opsworkscm.OpsWorksCmClient | 
| com.amazonaws.services.organizations.AWSOrganizationsAsyncClient | software.amazon.awssdk.services.organizations.OrganizationsAsyncClient | 
| com.amazonaws.services.organizations.AWSOrganizationsClient | software.amazon.awssdk.services.organizations.OrganizationsClient | 
| com.amazonaws.services.pi.AWSPIAsyncClient | software.amazon.awssdk.services.pi.PiAsyncClient | 
| com.amazonaws.services.pi.AWSPIClient | software.amazon.awssdk.services.pi.PiClient | 
| com.amazonaws.services.pinpoint.AmazonPinpointAsyncClient | software.amazon.awssdk.services.pinpoint.PinpointAsyncClient | 
| com.amazonaws.services.pinpoint.AmazonPinpointClient | software.amazon.awssdk.services.pinpoint.PinpointClient | 
| com.amazonaws.services.polly.AmazonPollyAsyncClient | software.amazon.awssdk.services.polly.PollyAsyncClient | 
| com.amazonaws.services.polly.AmazonPollyClient | software.amazon.awssdk.services.polly.PollyClient | 
| com.amazonaws.services.pricing.AWSPricingAsyncClient | software.amazon.awssdk.services.pricing.PricingAsyncClient | 
| com.amazonaws.services.pricing.AWSPricingClient | software.amazon.awssdk.services.pricing.PricingClient | 
| com.amazonaws.services.rds.AmazonRDSAsyncClient | software.amazon.awssdk.services.rds.RdsAsyncClient | 
| com.amazonaws.services.rds.AmazonRDSClient | software.amazon.awssdk.services.rds.RdsClient | 
| com.amazonaws.services.redshift.AmazonRedshiftAsyncClient | software.amazon.awssdk.services.redshift.RedshiftAsyncClient | 
| com.amazonaws.services.redshift.AmazonRedshiftClient | software.amazon.awssdk.services.redshift.RedshiftClient | 
| com.amazonaws.services.rekognition.AmazonRekognitionAsyncClient | software.amazon.awssdk.services.rekognition.RekognitionAsyncClient | 
| com.amazonaws.services.rekognition.AmazonRekognitionClient | software.amazon.awssdk.services.rekognition.RekognitionClient | 
| com.amazonaws.services.resourcegroups.AWSResourceGroupsAsyncClient | software.amazon.awssdk.services.resourcegroups.ResourceGroupsAsyncClient | 
| com.amazonaws.services.resourcegroups.AWSResourceGroupsClient | software.amazon.awssdk.services.resourcegroups.ResourceGroupsClient | 
| com.amazonaws.services.resourcegroupstaggingapi.AWSResourceGroupsTaggingAPIAsyncClient | software.amazon.awssdk.services.resourcegroupstaggingapi.ResourceGroupsTaggingApiAsyncClient | 
| com.amazonaws.services.resourcegroupstaggingapi.AWSResourceGroupsTaggingAPIClient | software.amazon.awssdk.services.resourcegroupstaggingapi.ResourceGroupsTaggingApiClient | 
| com.amazonaws.services.route53.AmazonRoute53AsyncClient | software.amazon.awssdk.services.route53.Route53AsyncClient | 
| com.amazonaws.services.route53.AmazonRoute53Client | software.amazon.awssdk.services.route53.Route53Client | 
| com.amazonaws.services.route53domains.AmazonRoute53DomainsAsyncClient | software.amazon.awssdk.services.route53domains.Route53DomainsAsyncClient | 
| com.amazonaws.services.route53domains.AmazonRoute53DomainsClient | software.amazon.awssdk.services.route53domains.Route53DomainsClient | 
| com.amazonaws.services.s3.AmazonS3Client | software.amazon.awssdk.services.s3.S3Client | 
| com.amazonaws.services.sagemaker.AmazonSageMakerAsyncClient | software.amazon.awssdk.services.sagemaker.SageMakerAsyncClient | 
| com.amazonaws.services.sagemaker.AmazonSageMakerClient | software.amazon.awssdk.services.sagemaker.SageMakerClient | 
| com.amazonaws.services.sagemakerruntime.AmazonSageMakerRuntimeAsyncClient | software.amazon.awssdk.services.sagemakerruntime.SageMakerRuntimeAsyncClient | 
| com.amazonaws.services.sagemakerruntime.AmazonSageMakerRuntimeClient | software.amazon.awssdk.services.sagemakerruntime.SageMakerRuntimeClient | 
| com.amazonaws.services.secretsmanager.AWSSecretsManagerAsyncClient | software.amazon.awssdk.services.secretsmanager.SecretsManagerAsyncClient | 
| com.amazonaws.services.secretsmanager.AWSSecretsManagerClient | software.amazon.awssdk.services.secretsmanager.SecretsManagerClient | 
| com.amazonaws.services.securitytoken.AWSSecurityTokenServiceAsyncClient | software.amazon.awssdk.services.sts.StsAsyncClient | 
| com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient | software.amazon.awssdk.services.sts.StsClient | 
| com.amazonaws.services.serverlessapplicationrepository.AWSServerlessApplicationRepositoryAsyncClient | software.amazon.awssdk.services.serverlessapplicationrepository.ServerlessApplicationRepositoryAsyncClient | 
| com.amazonaws.services.serverlessapplicationrepository.AWSServerlessApplicationRepositoryClient | software.amazon.awssdk.services.serverlessapplicationrepository.ServerlessApplicationRepositoryClient | 
| com.amazonaws.services.servermigration.AWSServerMigrationAsyncClient | software.amazon.awssdk.services.sms.SmsAsyncClient | 
| com.amazonaws.services.servermigration.AWSServerMigrationClient | software.amazon.awssdk.services.sms.SmsClient | 
| com.amazonaws.services.servicecatalog.AWSServiceCatalogAsyncClient | software.amazon.awssdk.services.servicecatalog.ServiceCatalogAsyncClient | 
| com.amazonaws.services.servicecatalog.AWSServiceCatalogClient | software.amazon.awssdk.services.servicecatalog.ServiceCatalogClient | 
| com.amazonaws.services.servicediscovery.AWSServiceDiscoveryAsyncClient | software.amazon.awssdk.services.servicediscovery.ServiceDiscoveryAsyncClient | 
| com.amazonaws.services.servicediscovery.AWSServiceDiscoveryClient | software.amazon.awssdk.services.servicediscovery.ServiceDiscoveryClient | 
| com.amazonaws.services.shield.AWSShieldAsyncClient | software.amazon.awssdk.services.shield.ShieldAsyncClient | 
| com.amazonaws.services.shield.AWSShieldClient | software.amazon.awssdk.services.shield.ShieldClient | 
| com.amazonaws.services.simpledb.AmazonSimpleDBAsyncClient | software.amazon.awssdk.services.simpledb.SimpleDbAsyncClient | 
| com.amazonaws.services.simpledb.AmazonSimpleDBClient | software.amazon.awssdk.services.simpledb.SimpleDbClient | 
| com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceAsyncClient | software.amazon.awssdk.services.ses.SesAsyncClient | 
| com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient | software.amazon.awssdk.services.ses.SesClient | 
| com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementAsyncClient | software.amazon.awssdk.services.ssm.SsmAsyncClient | 
| com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClient | software.amazon.awssdk.services.ssm.SsmClient | 
| com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowAsyncClient | software.amazon.awssdk.services.swf.SwfAsyncClient | 
| com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClient | software.amazon.awssdk.services.swf.SwfClient | 
| com.amazonaws.services.snowball.AmazonSnowballAsyncClient | software.amazon.awssdk.services.snowball.SnowballAsyncClient | 
| com.amazonaws.services.snowball.AmazonSnowballClient | software.amazon.awssdk.services.snowball.SnowballClient | 
| com.amazonaws.services.sns.AmazonSNSAsyncClient | software.amazon.awssdk.services.sns.SnsAsyncClient | 
| com.amazonaws.services.sns.AmazonSNSClient | software.amazon.awssdk.services.sns.SnsClient | 
| com.amazonaws.services.sqs.AmazonSQSAsyncClient | software.amazon.awssdk.services.sqs.SqsAsyncClient | 
| com.amazonaws.services.sqs.AmazonSQSClient | software.amazon.awssdk.services.sqs.SqsClient | 
| com.amazonaws.services.stepfunctions.AWSStepFunctionsAsyncClient | software.amazon.awssdk.services.sfn.SfnAsyncClient | 
| com.amazonaws.services.stepfunctions.AWSStepFunctionsClient | software.amazon.awssdk.services.sfn.SfnClient | 
| com.amazonaws.services.storagegateway.AWSStorageGatewayAsyncClient | software.amazon.awssdk.services.storagegateway.StorageGatewayAsyncClient | 
| com.amazonaws.services.storagegateway.AWSStorageGatewayClient | software.amazon.awssdk.services.storagegateway.StorageGatewayClient | 
| com.amazonaws.services.support.AWSSupportAsyncClient | software.amazon.awssdk.services.support.SupportAsyncClient | 
| com.amazonaws.services.support.AWSSupportClient | software.amazon.awssdk.services.support.SupportClient | 
| com.amazonaws.services.transcribe.AmazonTranscribeAsyncClient | software.amazon.awssdk.services.transcribe.TranscribeAsyncClient | 
| com.amazonaws.services.transcribe.AmazonTranscribeClient | software.amazon.awssdk.services.transcribe.TranscribeClient | 
| com.amazonaws.services.translate.AmazonTranslateAsyncClient | software.amazon.awssdk.services.translate.TranslateAsyncClient | 
| com.amazonaws.services.translate.AmazonTranslateClient | software.amazon.awssdk.services.translate.TranslateClient | 
| com.amazonaws.services.waf.AWSWAFAsyncClient | software.amazon.awssdk.services.waf.WafAsyncClient | 
| com.amazonaws.services.waf.AWSWAFClient | software.amazon.awssdk.services.waf.WafClient | 
| com.amazonaws.services.waf.AWSWAFRegionalAsyncClient | software.amazon.awssdk.services.waf.regional.WafRegionalAsyncClient | 
| com.amazonaws.services.waf.AWSWAFRegionalClient | software.amazon.awssdk.services.waf.regional.WafRegionalClient | 
| com.amazonaws.services.workdocs.AmazonWorkDocsAsyncClient | software.amazon.awssdk.services.workdocs.WorkDocsAsyncClient | 
| com.amazonaws.services.workdocs.AmazonWorkDocsClient | software.amazon.awssdk.services.workdocs.WorkDocsClient | 
| com.amazonaws.services.workmail.AmazonWorkMailAsyncClient | software.amazon.awssdk.services.workmail.WorkMailAsyncClient | 
| com.amazonaws.services.workmail.AmazonWorkMailClient | software.amazon.awssdk.services.workmail.WorkMailClient | 
| com.amazonaws.services.workspaces.AmazonWorkspacesAsyncClient | software.amazon.awssdk.services.workspaces.WorkSpacesAsyncClient | 
| com.amazonaws.services.workspaces.AmazonWorkspacesClient | software.amazon.awssdk.services.workspaces.WorkSpacesClient | 
| com.amazonaws.services.xray.AWSXRayAsyncClient | software.amazon.awssdk.services.xray.XRayAsyncClient | 
| com.amazonaws.services.xray.AWSXRayClient | software.amazon.awssdk.services.xray.XRayClient | 

# 用戶端建立預設值
<a name="client-creation-defaults"></a>

在 2.x 版中，已對預設用戶端建立邏輯進行下列變更。
+ S3 的預設登入資料提供者鏈結不再包含匿名登入資料。您必須使用 手動指定對 S3 的匿名存取`AnonymousCredentialsProvider`。
+ 下列與預設用戶端建立相關的環境變數不同。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/client-creation-defaults.html)
+ 下列與預設用戶端建立相關的系統屬性不同。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/client-creation-defaults.html)
+ 2.x 版不支援下列系統屬性。
+     
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/client-creation-defaults.html)
+ 不再支援從自訂`endpoints.json`檔案載入區域組態。

# 用戶端組態
<a name="client-configuration"></a>

在 1.x 中，透過在用戶端或用戶端建置器上設定`ClientConfiguration`執行個體來修改 SDK 用戶端組態。在 2.x 版中，用戶端組態會分成個別的組態類別。使用不同的組態類別，您可以為非同步用戶端與同步用戶端設定不同的 HTTP 用戶端，但仍使用相同的`ClientOverrideConfiguration`類別。

**Example 1.x 版中的用戶端組態**  

```
AmazonDynamoDBClientBuilder.standard()
.withClientConfiguration(clientConfiguration)
.build()
```

**Example 2.x 版中的同步用戶端組態**  

```
ProxyConfiguration.Builder proxyConfig = ProxyConfiguration.builder();

ApacheHttpClient.Builder httpClientBuilder =
        ApacheHttpClient.builder()
                        .proxyConfiguration(proxyConfig.build());

ClientOverrideConfiguration.Builder overrideConfig =
        ClientOverrideConfiguration.builder();

DynamoDbClient client =
        DynamoDbClient.builder()
                      .httpClientBuilder(httpClientBuilder)
                      .overrideConfiguration(overrideConfig.build())
                      .build();
```

**Example 2.x 版中的非同步用戶端組態**  

```
NettyNioAsyncHttpClient.Builder httpClientBuilder =
        NettyNioAsyncHttpClient.builder();

ClientOverrideConfiguration.Builder overrideConfig =
        ClientOverrideConfiguration.builder();

ClientAsyncConfiguration.Builder asyncConfig =
        ClientAsyncConfiguration.builder();

DynamoDbAsyncClient client =
        DynamoDbAsyncClient.builder()
                           .httpClientBuilder(httpClientBuilder)
                           .overrideConfiguration(overrideConfig.build())
                           .asyncConfiguration(asyncConfig.build())
                           .build();
```

## HTTP 用戶端
<a name="client-configuration-http"></a>

### 顯著的變更
<a name="client-configuration-http-notables"></a>
+ 在 2.x 版中，您可以使用 指定實作，以變更要在執行時間使用的 HTTP 用戶端。 `clientBuilder.httpClientBuilder`
+ 當您使用 將 HTTP 用戶端傳遞`clientBuilder.httpClient`至服務用戶端建置器時，如果服務用戶端關閉，則 HTTP 用戶端預設不會關閉。這可讓您在服務用戶端之間共用 HTTP 用戶端。
+ 非同步 HTTP 用戶端現在使用非封鎖 IO。
+ 有些操作現在使用 HTTP/2 來改善效能。

### 設定變更
<a name="client-configuration-http-setting-diffs"></a>


| 設定 | 1.x | 2.x 同步、Apache | 2.x 非同步、Netty | 
| --- | --- | --- | --- | 
|  |  <pre>ClientConfiguration clientConfig = <br />    new ClientConfiguration()</pre>  |  <pre>ApacheHttpClient.Builder httpClientBuilder = <br />    ApacheHttpClient.builder()</pre>  |  <pre>NettyNioAsyncHttpClient.Builder httpClientBuilder = <br />    NettyNioAsyncHttpClient.builder()</pre>  | 
| 連線數量上限 |  <pre>clientConfig.setMaxConnections(...)<br />clientConfig.withMaxConnections(...)</pre>  |  <pre>httpClientBuilder.maxConnections(...)</pre>  |  <pre>httpClientBuilder.maxConcurrency(...)</pre>  | 
| 連線逾時 |  <pre>clientConfig.setConnectionTimeout(...)<br />clientConfig.withConnectionTimeout(...)</pre>  |  <pre>httpClientBuilder.connectionTimeout(...)<br />httpClientBuilder.connectionAcquisitionTimeout(...)</pre>  |  <pre>httpClientBuilder.connectionTimeout(...)</pre>  | 
| 通訊端逾時 |  <pre>clientConfig.setSocketTimeout(...)<br />clientConfig.withSocketTimeout(...)</pre>  |  <pre>httpClientBuilder.socketTimeout(...)</pre>  |  <pre>httpClientBuilder.writeTimeout(...)<br />httpClientBuilder.readTimeout(...)</pre>  | 
| 連線 TTL |  <pre>clientConfig.setConnectionTTL(...)<br />clientConfig.withConnectionTTL(...)</pre>  |  <pre>httpClientBuilder.connectionTimeToLive(...)</pre>  |  <pre>httpClientBuilder.connectionTimeToLive(...)</pre>  | 
| 連線閒置上限 |  <pre>clientConfig.setConnectionMaxIdleMillis(...)<br />clientConfig.withConnectionMaxIdleMillis(...)</pre>  |  <pre>httpClientBuilder.connectionMaxIdleTime(...)</pre>  |  <pre>httpClientBuilder.connectionMaxIdleTime(...)</pre>  | 
| 閒置後驗證 |  <pre>clientConfig.setValidateAfterInactivityMillis(...)<br />clientConfig.withValidateAfterInactivityMillis(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| 本機地址 |  <pre>clientConfig.setLocalAddress(...)<br />clientConfig.withLocalAddress(...)</pre>  |  <pre>httpClientBuilder.localAddress(...)</pre>  | [不支援](https://github.com/aws/aws-sdk-java-v2/issues/857) | 
| Expect-continue 已啟用 |  <pre>clientConfig.setUseExpectContinue(...)<br />clientConfig.withUseExpectContinue(...)</pre>  |  <pre>httpClientBuilder.expectContinueEnabled(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| 連線解析程式 |  <pre>clientConfig.setUseReaper(...)<br />clientConfig.withReaper(...)</pre>  |  <pre>httpClientBuilder.useIdleConnectionReaper(...)</pre>  |  <pre>httpClientBuilder.useIdleConnectionReaper(...)</pre>  | 
|  |  <pre>AmazonDynamoDBClientBuilder.standard()<br />    .withClientConfiguration(clientConfiguration)<br />    .build()</pre>  |  <pre>DynamoDbClient.builder()<br />    .httpClientBuilder(httpClientBuilder)<br />    .build()</pre>  |  <pre>DynamoDbAsyncClient.builder()<br />.httpClientBuilder(httpClientBuilder)<br />.build()</pre>  | 

## HTTP 用戶端代理
<a name="client-configuration-http-proxy"></a>


| 設定 | 1.x | 2.x 同步、Apache | 2.x 非同步、Netty | 
| --- | --- | --- | --- | 
|  |  <pre>ClientConfiguration clientConfig =<br />    new ClientConfiguration()</pre>  |  <pre>ProxyConfiguration.Builder proxyConfig =<br />    ProxyConfiguration.builder()</pre>  |  <pre>ProxyConfiguration.Builder proxyConfig =<br />    ProxyConfiguration.builder()</pre>  | 
| 代理主機 |  <pre>clientConfig.setProxyHost(...)<br />clientConfig.withProxyHost(...)</pre>  |  <pre>proxyConfig.endpoint(...)</pre>  |  <pre>proxyConfig.host(...)</pre>  | 
| 代理連接埠 |  <pre>clientConfig.setProxyPort(...)<br />clientConfig.withProxyPort(...)</pre>  |  <pre>proxyConfig.endpoint(...)</pre> [Proxy 連接埠](http-configuration-apache.md#http-configuration-apache-proxy-conf-ex)內嵌於 `endpoint`  |  <pre>proxyConfig.port(...)</pre>  | 
| 代理使用者名稱 |  <pre>clientConfig.setProxyUsername(...)<br />clientConfig.withProxyUsername(...)</pre>  |  <pre>proxyConfig.username(...)</pre>  |  <pre>proxyConfig.username(...)</pre>  | 
| 代理密碼 |  <pre>clientConfig.setProxyPassword(...)<br />clientConfig.withProxyPassword(...)</pre>  |  <pre>proxyConfig.password(...)</pre>  |  <pre>proxyConfig.password(...)</pre>  | 
| Proxy 網域 |  <pre>clientConfig.setProxyDomain(...)<br />clientConfig.withProxyDomain(...)</pre>  |  <pre>proxyConfig.ntlmDomain(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| Proxy 工作站 |  <pre>clientConfig.setProxyWorkspace(...)<br />clientConfig.withProxyWorkstation(...)</pre>  |  <pre>proxyConfig.ntlmWorkstation(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| Proxy 身分驗證方法 |  <pre>clientConfig.setProxyAuthenticationMethods(...)<br />clientConfig.withProxyAuthenticationMethods(...)</pre>  |  [不支援](https://github.com/aws/aws-sdk-java-v2/issues/858)  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| 先佔型基本代理身分驗證 |  <pre>clientConfig.setPreemptiveBasicProxyAuth(...)<br />clientConfig.withPreemptiveBasicProxyAuth(...)</pre>  |  <pre>proxyConfig.preemptiveBasicAuthenticationEnabled(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| 非代理主機 |  <pre>clientConfig.setNonProxyHosts(...)<br />clientConfig.withNonProxyHosts(...)</pre>  |  <pre>proxyConfig.nonProxyHosts(...)</pre>  |  <pre>proxyConfig.nonProxyHosts(...)</pre>  | 
| 停用通訊端代理 |  <pre>clientConfig.setDisableSocketProxy(...)<br />clientConfig.withDisableSocketProxy(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
|  |  <pre>AmazonDynamoDBClientBuilder.standard()<br />    .withClientConfiguration(clientConfiguration)<br />    .build()</pre>  |  <pre>httpClientBuilder.proxyConfiguration(<br />    proxyConfig.build())</pre>  |  <pre>httpClientBuilder.proxyConfiguration(<br />    proxyConfig.build())</pre>  | 

## 用戶端覆寫
<a name="client-override-config-diffs"></a>


| 設定 | 1.x | 2.x | 
| --- | --- | --- | 
|  |  <pre>ClientConfiguration clientConfig =<br />    new ClientConfiguration()</pre>  |  <pre>ClientOverrideConfiguration.Builder overrideConfig =<br />    ClientOverrideConfiguration.builder()</pre>  | 
| 使用者代理程式字首 |  <pre>clientConfig.setUserAgentPrefix(...)<br />clientConfig.withUserAgentPrefix(...)</pre>  |  <pre>overrideConfig.advancedOption(<br />    SdkAdvancedClientOption.USER_AGENT_PREFIX, ...)</pre>  | 
| 使用者代理程式尾碼 |  <pre>clientConfig.setUserAgentSuffix(...)<br />clientConfig.withUserAgentSuffix(...)</pre>  |  <pre>overrideConfig.advancedOption(<br />    SdkAdvancedClientOption.USER_AGENT_SUFFIX, ...)</pre>  | 
| Signer |  <pre>clientConfig.setSignerOverride(...)<br />clientConfig.withSignerOverride(...)</pre>  |  <pre>overrideConfig.advancedOption(<br />    SdkAdvancedClientOption.SIGNER, ...)</pre>  | 
| 其他標頭 |  <pre>clientConfig.addHeader(...)<br />clientConfig.withHeader(...)</pre>  |  <pre>overrideConfig.putHeader(...)</pre>  | 
| 請求逾時 |  <pre>clientConfig.setRequestTimeout(...)<br />clientConfig.withRequestTimeout(...)</pre>  |  <pre>overrideConfig.apiCallAttemptTimeout(...)</pre>  | 
| 用戶端執行逾時 |  <pre>clientConfig.setClientExecutionTimeout(...)<br />clientConfig.withClientExecutionTimeout(...)</pre>  |  <pre>overrideConfig.apiCallTimeout(...)</pre>  | 
| 使用 Gzip |  <pre>clientConfig.setUseGzip(...)<br />clientConfig.withGzip(...)</pre>  |  不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new))  | 
| 通訊端緩衝區大小提示 |  <pre>clientConfig.setSocketBufferSizeHints(...)<br />clientConfig.withSocketBufferSizeHints(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| 快取回應中繼資料 |  <pre>clientConfig.setCacheResponseMetadata(...)<br />clientConfig.withCacheResponseMetadata(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| 回應中繼資料快取大小 |  <pre>clientConfig.setResponseMetadataCacheSize(...)<br />clientConfig.withResponseMetadataCacheSize(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| DNS 解析程式 |  <pre>clientConfig.setDnsResolver(...)<br />clientConfig.withDnsResolver(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
| TCP 保持連線 |  <pre>clientConfig.setUseTcpKeepAlive(...)<br />clientConfig.withTcpKeepAlive(...)</pre>  |  此選項現在位於 HTTP 用戶端組態中 <pre>- ApacheHttpClient.builder().tcpKeepAlive(true)<br />- NettyNioAsyncHttpClient.builder().tcpKeepAlive(true)</pre>  | 
| 安全隨機 |  <pre>clientConfig.setSecureRandom(...)<br />clientConfig.withSecureRandom(...)</pre>  | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
|  |  <pre>AmazonDynamoDBClientBuilder.standard()<br />    .withClientConfiguration(clientConfiguration)<br />    .build()</pre>  |  <pre>DynamoDbClient.builder()<br />    .overrideConfiguration(overrideConfig.build())<br />    .build()</pre>  | 

## 用戶端覆寫重試
<a name="client-override-retry-config-diffs"></a>


| 設定 | 1.x | 2.x | 
| --- | --- | --- | 
|  |  <pre>ClientConfiguration clientConfig =<br />    new ClientConfiguration()</pre>  |  <pre>ClientOverrideConfiguration.Builder overrideConfigBuilder = <br />    ClientOverrideConfiguration.builder();</pre>  | 
| 重試錯誤上限 |  <pre>clientConfig.setMaxErrorRetry(...)<br />clientConfig.withMaxErrorRetry(...)</pre>  |  <pre>// Configure the default retry strategy.<br />overrideConfigBuilder.retryStrategy(b -> b.maxAttempts(...));</pre>  | 
| 使用限流重試 |  <pre>clientConfig.setUseThrottleRetries(...)<br />clientConfig.withUseThrottleRetries(...)</pre>  | [不支援](https://github.com/aws/aws-sdk-java-v2/issues/645) | 
| 限流前的連續重試次數上限 |  <pre>clientConfig.setMaxConsecutiveRetriesBeforeThrottling(...)<br />clientConfig.withMaxConsecutiveRetriesBeforeThrottling(...)</pre>  | [不支援](https://github.com/aws/aws-sdk-java-v2/issues/645) | 
|  |  <pre>AmazonDynamoDBClientBuilder.standard()<br />    .withClientConfiguration(clientConfiguration)<br />    .build()</pre>  |  <pre>DynamoDbClient.builder()<br />        .overrideConfiguration(overrideConfigBuilder.build())<br />        .build();<br /><br />// You also have the option to use a lambda expression to configure and<br />// build the 'ClientOverrideConfiguration.Builder'.<br />DynamoDbClient client = DynamoDbClient.builder()<br />        .overrideConfiguration(o -> o.retryStrategy(b -> b.maxAttempts(5)))<br />        .build();</pre>  | 

## 非同步用戶端
<a name="client-async-config-diffs"></a>


| 設定 | 1.x | 2.x | 
| --- | --- | --- | 
|  |  |  <pre>ClientAsyncConfiguration.Builder asyncConfig =<br />    ClientAsyncConfiguration.builder()</pre>  | 
| 執行器 |  <pre>AmazonDynamoDBAsyncClientBuilder.standard()<br />    .withExecutorFactory(...)<br />    .build()</pre>  |  <pre>asyncConfig.advancedOption(<br />    SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR, ...)</pre>  | 
|  |  |  <pre>DynamoDbAsyncClient.builder()<br />    .asyncConfiguration(asyncConfig)<br />    .build()</pre>  | 

## 其他用戶端變更
<a name="client-config-other-diffs"></a>

來自 1.x 的下列`ClientConfiguration`選項已在 SDK 的 2.x 中變更，並且沒有直接對等項目。


| 設定 | 1.x | 2.x 同等 | 
| --- | --- | --- | 
| 通訊協定 |  <pre>clientConfig.setProtocol(Protocol.HTTP)<br />clientConfig.withProtocol(Protocol.HTTP)</pre>  |  根據預設，通訊協定設定為 HTTPS。若要修改設定，請指定在用戶端建置器上設定 HTTP 端點的通訊協定： <pre>clientBuilder.endpointOverride(<br />    URI.create("http://..."))</pre>  | 

# 登入資料提供者變更
<a name="migration-client-credentials"></a>

本節提供 1.x 和 2.x 版之間登入資料提供者類別和方法名稱變更的映射 適用於 Java 的 AWS SDK。

## 顯著差異
<a name="client-credentials"></a>
+ 預設登入資料提供者會在 2.x 版中先載入系統屬性，再載入環境變數。如需詳細資訊，請參閱[使用登入](credentials.md)資料。
+ 建構函數方法被 `create` 或 `builder` 方法取代。  
**Example**  

  ```
  DefaultCredentialsProvider.create();
  ```
+ 預設值已不再是非同步重新整理。您必須以登入資料提供者的 `builder` 指定非同步重新整理。  
**Example**  

  ```
  ContainerCredentialsProvider provider = ContainerCredentialsProvider.builder()
          		.asyncCredentialUpdateEnabled(true)
          		.build();
  ```
+ 您可以使用 `ProfileCredentialsProvider.builder()` 指定自訂設定檔的路徑。  
**Example**  

  ```
  ProfileCredentialsProvider profile = ProfileCredentialsProvider.builder()
          		.profileFile(ProfileFile.builder().content(Paths.get("myProfileFile.file")).build())
          		.build();
  ```
+ 設定檔格式已變更，以更符合 AWS CLI。如需詳細資訊，請參閱*AWS Command Line Interface 《 使用者指南*》中的[設定 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)。

## 對應至 1.x 和 2.x 版之間的登入資料提供者變更
<a name="credentials-changes-mapping"></a>

### `AWSCredentialsProvider`
<a name="credentials-provider-changes-AWSCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.AWSCredentialsProvider | software.amazon.awssdk.auth.credentials.AwsCredentialsProvider | 
| 方法名稱 | getCredentials | resolveCredentials | 
| 不支援的方法 | refresh | 不支援 | 

### `DefaultAWSCredentialsProviderChain`
<a name="credentials-provider-changes-DefaultAWSCredentialsProviderChain"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.DefaultAWSCredentialsProviderChain | software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider | 
| 建立 | new DefaultAWSCredentialsProviderChain | DefaultCredentialsProvider.create | 
| 不支援的方法 | getInstance | 不支援 | 
| 外部設定的優先順序 |  系統屬性之前的環境變數  |  環境變數之前的系統屬性  | 

### `AWSStaticCredentialsProvider`
<a name="credentials-provider-changes-AWSStaticCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.AWSStaticCredentialsProvider | software.amazon.awssdk.auth.credentials.StaticCredentialsProvider | 
| 建立 | new AWSStaticCredentialsProvider | StaticCredentialsProvider.create | 

### `EnvironmentVariableCredentialsProvider`
<a name="credentials-provider-changes-EnvironmentVariableCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.EnvironmentVariableCredentialsProvider | software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider | 
| 建立 | new EnvironmentVariableCredentialsProvider | EnvironmentVariableCredentialsProvider.create | 
| 環境變數名稱 | AWS\$1ACCESS\$1KEY | AWS\$1ACCESS\$1KEY\$1ID | 
|  | AWS\$1SECRET\$1KEY | AWS\$1SECRET\$1ACCESS\$1KEY | 

### `SystemPropertiesCredentialsProvider`
<a name="credentials-provider-changes-SystemPropertiesCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.SystemPropertiesCredentialsProvider | software.amazon.awssdk.auth.credentials.SystemPropertyCredentialsProvider | 
| 建立 | new SystemPropertiesCredentialsProvider | SystemPropertiesCredentialsProvider.create | 
| 系統屬性名稱 | aws.secretKey | aws.secretAccessKey | 

### `ProfileCredentialsProvider`
<a name="credentials-provider-changes-ProfileCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.profile.ProfileCredentialsProvider | software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider | 
| 建立 | new ProfileCredentialsProvider | ProfileCredentialsProvider.create | 
| 自訂設定檔的位置 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/migration-client-credentials.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/migration-client-credentials.html)  | 

### `ContainerCredentialsProvider`
<a name="credentials-provider-changes-ContainerCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.ContainerCredentialsProvider | software.amazon.awssdk.auth.credentials.ContainerCredentialsProvider | 
| 建立 | new ContainerCredentialsProvider | ContainerCredentialsProvider.create | 
| 指定非同步重新整理 | 不支援 | 預設行為 | 

### `InstanceProfileCredentialsProvider`
<a name="credentials-provider-changes-InstanceProfileCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.InstanceProfileCredentialsProvider | software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider | 
| 建立 | new InstanceProfileCredentialsProvider | InstanceProfileCredentialsProvider.create | 
| 指定非同步重新整理 | new InstanceProfileCredentialsProvider(true) |  `InstanceProfileCredentialProvider.builder().asyncCredentialUpdateEnabled(true).build()`  | 
| 系統屬性名稱 | com.amazonaws.sdk.disableEc2Metadata | aws.disableEc2Metadata | 
|  | com.amazonaws.sdk.ec2MetadataServiceEndpointOverride | aws.ec2MetadataServiceEndpoint | 

### `STSAssumeRoleSessionCredentialsProvider`
<a name="credentials-provider-changes-STSAssumeRoleSessionCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider | software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider | 
| 建立 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/migration-client-credentials.html)  | StsAssumeRoleCredentialsProvider.builder | 
| 非同步重新整理 | 預設行為 | 預設行為 | 
| 組態 | new STSAssumeRoleSessionCredentialsProvider.Builder | 設定 StsClient和 AssumeRoleRequest請求 | 

### `STSSessionCredentialsProvider`
<a name="credentials-provider-changes-STSSessionCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.STSSessionCredentialsProvider | software.amazon.awssdk.services.sts.auth.StsGetSessionTokenCredentialsProvider | 
| 建立 |  `new STSSessionCredentialsProvider`  | StsGetSessionTokenCredentialsProvider.builder | 
| 非同步重新整理 | 預設行為 | StsGetSessionTokenCredentialsProvider.builder | 
| 組態 | 建構器參數 | 在建置器中設定 StsClient和 GetSessionTokenRequest請求 | 

### `WebIdentityFederationSessionCredentialsProvider`
<a name="credentials-provider-changes-WebIdentityFederationSessionCredentialsProvider"></a>


| 變更類別 | 1.x | 2.x | 
| --- | --- | --- | 
| 套件/類別名稱 | com.amazonaws.auth.WebIdentityFederationSessionCredentialsProvider | software.amazon.awssdk.services.sts.auth.StsAssumeRoleWithWebIdentityCredentialsProvider | 
| 建立 |  `new WebIdentityFederationSessionCredentialsProvider`  | StsAssumeRoleWithWebIdentityCredentialsProvider.builder | 
| 非同步重新整理 | 預設行為 | StsAssumeRoleWithWebIdentityCredentialsProvider.builder | 
| 組態 | 建構器參數 | 在建置器中設定 StsClient和 AssumeRoleWithWebIdentityRequest請求 | 

### 已取代類別
<a name="credentials-provider-changes-Replacements"></a>


| 1.x 類別 | 2.x 替換類別 | 
| --- | --- | 
| com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper | software.amazon.awssdk.auth.credentials.ContainerCredentialsProvider 和 software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider | 
| com.amazonaws.services.s3.S3CredentialsProviderChain | software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider 和 software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider | 

### 已移除類別
<a name="credentials-provider-changes-Removed"></a>


| 1.x 類別 | 
| --- | 
| com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider | 
| com.amazonaws.auth.PropertiesFileCredentialsProvider | 

# 區域變更
<a name="migration-client-region"></a>

本節說明 適用於 Java 的 AWS SDK 2.x 中針對使用 `Region`和 `Regions`類別實作的變更。

## 區域組態
<a name="region-configuration"></a>
+ 有些 AWS 服務沒有區域特定的端點。使用這些服務時，您必須將區域設為 `Region.AWS_GLOBAL` 或 `Region.AWS_CN_GLOBAL`。  
**Example**  

  ```
  Region region = Region.AWS_GLOBAL;
  ```
+  `com.amazonaws.regions.Regions` 和 `com.amazonaws.regions.Region` 類別現在已合併成一個類別 `software.amazon.awssdk.regions.Region`。

## 方法和類別名稱映射
<a name="region-method-mapping"></a>

下表映射 1.x 和 2.x 版之間的區域相關類別 適用於 Java 的 AWS SDK。您可以使用 `of()` 方法建立這些類別的執行個體。

**Example**  

```
RegionMetadata regionMetadata = RegionMetadata.of(Region.US_EAST_1);
```


**1.x 區域類別方法變更**  

| 1.x | 2.x | 
| --- | --- | 
|  `Regions.fromName`  |  `Region.of`  | 
|  `Regions.getName`  |  `Region.id`  | 
|  `Regions.getDescription`  |  `Region.metadata().description()`  | 
|  `Regions.getCurrentRegion`  |  不支援  | 
|  `Regions.DEFAULT_REGION`  |  不支援  | 
|  `Regions.name`  |  `Region.id`  | 


**1.x 區域類別方法變更**  

| 1.x | 2.x | 
| --- | --- | 
|  `Region.getName`  |  `Region.id`  | 
|  `Region.hasHttpsEndpoint`  |  不支援  | 
|  `Region.hasHttpEndpoint`  |  不支援  | 
|  `Region.getAvailableEndpoints`  |  不支援  | 
|  `Region.createClient`  |  不支援  | 


**RegionMetadata 類別方法變更**  

| 1.x | 2.x | 
| --- | --- | 
|  `RegionMetadata.getName`  |  `RegionMetadata.name`  | 
|  `RegionMetadata.getDomain`  |  `RegionMetadata.domain`  | 
|  `RegionMetadata.getPartition`  |  `RegionMetadata.partition`  | 


**ServiceMetadata 類別方法變更**  

| 1.x | 2.x | 
| --- | --- | 
|  `Region.getServiceEndpoint`  |  `ServiceMetadata.endpointFor(Region)`  | 
|  `Region.isServiceSupported`  |  `ServiceMetadata.regions().contains(Region)`  | 

# 操作、請求和回應變更
<a name="migration-operation-requests-responses"></a>

在適用於 Java 的 開發套件第 2 版中，請求會傳遞至用戶端操作。例如`DynamoDbClient's``PutItemRequest`， 會傳遞至 `DynamoDbClient.putItem`操作。這些操作會從 傳回回應 AWS 服務，例如 `PutItemResponse`。

適用於 Java 的 SDK 第 2 版從第 1 版進行下列變更。
+ 具有多個回應頁面的操作現在有`Paginator`一種方法來自動逐一查看回應中的所有項目。
+ 您無法變更請求和回應。
+ 您必須使用靜態建置器方法來建立請求和回應，而不是建構函數。例如，第 1 版現在`new PutItemRequest().withTableName(...)`是 `PutItemRequest.builder().tableName(...).build()`。
+ 操作支援建立請求的速記方式：`dynamoDbClient.putItem(request -> request.tableName(...))`。

下列各節說明第 1 版和第 2 版之間的特定變更。有些參數類型變更可以使用[遷移工具](migration-tool.md)自動轉換，而其他變更則需要手動更新程式碼。

# 日期參數變更
<a name="migration-date-parameters"></a>

在第 1 版中，許多操作接受以時間為基礎的參數`java.util.Date`物件。在第 2 版中，這些操作會改用 `java.time.Instant` 物件。

您可以使用[遷移工具](migration-tool.md)自動轉換`Date`參數，也可以在`Date`物件上呼叫 `toInstant()`方法手動轉換參數。

**Example - 在版本 1 中產生具有過期日期的預先簽章 URL**  

```
// Generate a presigned URL that expires at a specific date
Date expiration = new Date(System.currentTimeMillis() + 3600000); // 1 hour from now
URL presignedUrl = s3Client.generatePresignedUrl(bucketName, keyName, expiration);
```

**Example - 在版本 2 中產生具有立即過期的預先簽章 URL**  

```
// Generate a presigned URL that expires at a specific instant
Date expiration = new Date(System.currentTimeMillis() + 3600000); // 1 hour from now
PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(
    GetObjectPresignRequest.builder()
        .getObjectRequest(GetObjectRequest.builder()
            .bucket(bucketName)
            .key(keyName)
            .build())
        .signatureDuration(Duration.between(Instant.now(), expiration.toInstant()))
        .build());
```

# 二進位資料處理變更
<a name="migration-binary-data"></a>

在第 1 版中，二進位資料是直接使用 `ByteBuffer` 物件處理。在第 2 版中，軟體開發套件使用`SdkBytes`物件，提供更便利且類型安全的方式來使用二進位資料。

您可以使用[遷移工具](migration-tool.md)`ByteBuffer`自動`SdkBytes`轉換為 ，也可以在傳回的`SdkBytes`物件`asByteBuffer()`上呼叫 ，手動將其轉換為 。

**Example - 從第 1 版中的訊息屬性取得二進位資料**  

```
// Get binary data from a message attribute
MessageAttributeValue messageAttributeValue = new MessageAttributeValue();
ByteBuffer binaryValue = messageAttributeValue.getBinaryValue();
String binaryString = new String(messageAttributeValue.getBinaryValue().array());
```

**Example - 從第 2 版中的訊息屬性取得二進位資料**  

```
// Get binary data from a message attribute
MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder().build();
ByteBuffer binaryValue = messageAttributeValue.binaryValue().asByteBuffer();
String binaryString = new String(messageAttributeValue.binaryValue().asByteBuffer().array());
```

# 逾時參數變更
<a name="migration-timeout-parameters"></a>

在第 1 版中，逾時值指定為整數值，代表毫秒。在第 2 版中，逾時參數會使用`java.time.Duration`物件，以獲得更好的類型安全性和清晰度。

您可以使用[遷移工具](migration-tool.md)自動轉換數值逾時值，也可以使用適當的`Duration`原廠方法包裝數值來手動轉換。

**Example - 在第 1 版中設定請求逾時**  

```
// Set request timeout in milliseconds
ClientConfiguration clientConfiguration = new ClientConfiguration();
clientConfiguration.setRequestTimeout(5000); // 5 seconds
```

**Example - 在第 2 版中設定請求逾時**  

```
// Set request timeout using Duration
ClientConfiguration clientConfiguration = new ClientConfiguration();
clientConfiguration.setRequestTimeout(Duration.ofMillis(5000)); // 5 seconds

// Or more clearly:
clientConfiguration.setRequestTimeout(Duration.ofSeconds(5)); // 5 seconds
```

您可以針對逾時值使用下列`Duration`原廠方法：
+ `Duration.ofMillis(long millis)` - 用於毫秒值。
+ `Duration.ofSeconds(long seconds)` - 用於第二個值。
+ `Duration.ofMinutes(long minutes)` - 用於分鐘值。

# 1.x 和 2.x 之間的串流操作差異 適用於 Java 的 AWS SDK
<a name="migration-streaming-ops"></a>

串流操作，例如 Amazon S3 `getObject`和 `putObject` 方法，支援 SDK 2.x 版中的非封鎖 I/O。因此，請求和回應模型物件不再以 `InputStream`做為參數。相反地，對於同步請求，請求物件接受 `RequestBody`，這是位元組串流。非同步對等項目接受 `AsyncRequestBody`。

**Example 1.x 中 Amazon S3 `putObject`操作的**  

```
s3client.putObject(BUCKET, KEY, new File(file_path));
```

**Example 2.x 中的 Amazon S3 `putObject`操作**  

```
s3client.putObject(PutObjectRequest.builder()
                                 .bucket(BUCKET)
                                 .key(KEY)
                                 .build(),
                 RequestBody.of(Paths.get("myfile.in")));
```

串流回應物件接受同步用戶端`ResponseTransformer`的 ，以及 V2 中非同步用戶端`AsyncResponseTransformer`的 。

**Example 1.x 中 Amazon S3 `getObject`操作的**  

```
S3Object o = s3.getObject(bucket, key);
S3ObjectInputStream s3is = o.getObjectContent();
FileOutputStream fos = new FileOutputStream(new File(key));
```

**Example 2.x 中的 Amazon S3 `getObject`操作**  

```
s3client.getObject(GetObjectRequest.builder().bucket(bucket).key(key).build(),
		ResponseTransformer.toFile(Paths.get("key")));
```

在適用於 Java 的 SDK 2.x 中，串流回應操作具有將回應載入記憶體`AsBytes`的方法，並簡化記憶體中的常見類型轉換。

# 1.x 和 2.x 之間的序列化差異 適用於 Java 的 AWS SDK
<a name="migration-serialization-changes"></a>

## 列出要請求參數差異的物件
<a name="serialization-diffs-list-obj-to-req-param"></a>

適用於 Java 的 SDK v1.x 和 v2.x 在序列化清單物件以請求參數方面有所不同。

適用於 Java 的 SDK 1.x 不會序列化空白清單，而適用於 Java 的 SDK 2.x 會將空白清單序列化為空白參數。

例如，請考慮具有需要 `SampleOperation`之 的服務`SampleRequest`。`SampleRequest` 接受兩個參數：字串類型`str1`和清單類型`listParam`，如下列範例所示。

**Example 1.x `SampleOperation`中的**  

```
SampleRequest v1Request = new SampleRequest()
    .withStr1("TestName");

sampleServiceV1Client.sampleOperation(v1Request);
```
線路層級記錄顯示 `listParam` 參數未序列化。  

```
Action=SampleOperation&Version=2011-01-01&str1=TestName
```

**Example 2.x `SampleOperation`中的**  

```
sampleServiceV2Client.sampleOperation(b -> b
    .str1("TestName"));
```
線路層級記錄顯示 `listParam` 參數已序列化，沒有值。  

```
Action=SampleOperation&Version=2011-01-01&str1=TestName&listParam=
```

## V1 POJOs 相較於 V2 中的建置器
<a name="serialization-json-objects"></a>

由於適用於 Java 的 V1 開發套件使用可變 POJO 類別，因此序列化和還原序列化程式庫 - 例如 [Jackson](https://github.com/FasterXML/jackson-docs) - 可以直接使用模型物件。

相比之下，適用於 Java 的 V2 開發套件使用不可變的模型物件。您必須使用中繼建置器來執行去序列化。

下列範例顯示使用 Jackson 取消序列化具有 V1 和 V2 的 `headBucket` API 呼叫之間的差異`ObjectMapper`。

```
    public void sendRequest() throws IOException {
        final String bucketName = "amzn-s3-demo-bucket";
        final ObjectMapper mapper = new ObjectMapper();

        // V1 uses POJOs to serialize and deserialize.
        final AmazonS3 v1S3Client = AmazonS3ClientBuilder.defaultClient();
        HeadBucketResult resultV1 = v1S3Client.headBucket(
            new HeadBucketRequest(bucketName));

        String v1Serialized = mapper.writeValueAsString(resultV1);

        HeadBucketResult deserializedV1 = mapper.readValue(v1Serialized, HeadBucketResult.class);
        
        // V2 uses builders to serialize and deserialize.
        S3Client v2S3Client = S3Client.create();
        HeadBucketResponse v2Response = v2S3Client.headBucket(
            b -> b.bucket(bucketName));

        String v2Serialized = mapper.writeValueAsString(
            v2Response.toBuilder());

        HeadBucketResponse v2Deserialized = mapper.readValue(
            v2Serialized, HeadBucketResponse.serializableBuilderClass())
            .build();
    }
```

# 1.x 和 2.x 之間的還原序列化差異 適用於 Java 的 AWS SDK
<a name="migration-deserialization-changes"></a>

## 與 V2 `nulls`中的空集合 V1
<a name="deserialization-diffs-list-obj-to-req-param"></a>

適用於 Java 的 SDK v1.x 和 v2.x 不同之處在於它們使用空白的清單和映射來還原序列化 JSON 回應。

當 SDK 收到含有以清單或映射建模之遺失屬性的回應時，V1 會將遺失屬性還原序列化為 `null`，而 V2 會將屬性還原序列化為不可變的空白集合物件。

例如，請考慮從 DynamoDB 用戶端傳回的 `describeTable`方法回應。下列範例方法包含 V2 DynamoDB 用戶端和 V1 DynamoDB 用戶端，兩者都在沒有全域次要索引的資料表上執行 `describeTable`方法

**Example 將建模為回應中遺失清單之屬性的還原序列化**  

```
public void deserializationDiffs(){

    DescribeTableResponse v2Response = dynamoDbClientV2.describeTable(builder -> builder.tableName(TABLE_NAME));
    // V2 provides has* methods on model objects for list/map members. No null check needed.
    LOGGER.info( String.valueOf(v2Response.table().hasGlobalSecondaryIndexes()) );
    LOGGER.info( String.valueOf(v2Response.table().globalSecondaryIndexes().isEmpty()) );
    // V2 deserialize to an empty collection.
    LOGGER.info(v2Response.table().globalSecondaryIndexes().toString());

    // V1 deserialize to null.
    DescribeTableResult v1Result = dynamoDbClientV1.describeTable(new DescribeTableRequest(TABLE_NAME));
    if (v1Result.getTable().getGlobalSecondaryIndexes() != null){
        LOGGER.info(v1Result.getTable().getGlobalSecondaryIndexes().toString());
    } else {
        LOGGER.info("The list of global secondary indexes returned by the V1 call is <null>");
    }
}
```
以下顯示記錄的輸出：  

```
INFO  org.example.DeserializationDifferences:45 - false
INFO  org.example.DeserializationDifferences:46 - true
INFO  org.example.DeserializationDifferences:48 - []
INFO  org.example.DeserializationDifferences:55 - The list of global secondary indexes returned by the V1 call is <null>
```

Java SDK 2.x 透過還原序列化空清單並映射到不可變的空集合，而不是傳回 `null`，以採取栩栩如生的方法，提升更安全、更簡潔的程式碼。使用 V2，您可以檢查服務是否傳回建模為清單的屬性，或使用 `has*`方法映射，例如上一個範例中`hasGlobalSecondaryIndexes`顯示的 。

此方法可避免需要明確`null`檢查，並符合處理不存在或空白資料結構的現代 Java 最佳實務。

### 完成範例
<a name="full-example-deserialization"></a>

```
package org.example;

import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
import com.amazonaws.services.dynamodbv2.model.DescribeTableResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.BillingMode;
import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse;
import software.amazon.awssdk.services.dynamodb.model.KeyType;
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;

import java.util.UUID;

public class DeserializationDifferences {
    private static final Logger LOGGER = LoggerFactory.getLogger(DeserializationDifferences.class);
    private static final String TABLE_NAME = "DeserializationTable-" + UUID.randomUUID();
    DynamoDbClient dynamoDbClientV2 = DynamoDbClient.create();
    AmazonDynamoDB dynamoDbClientV1 = AmazonDynamoDBClientBuilder.standard().withRegion(Regions.US_EAST_1).build();

    public static void main(String[] args) {

        DeserializationDifferences difference = new DeserializationDifferences();
        difference.createTable();
        difference.deserializationDiffs();
        difference.deleteTable();
    }

    public void createTable(){
        dynamoDbClientV2.createTable(b -> b
                .billingMode(BillingMode.PAY_PER_REQUEST)
                .tableName(TABLE_NAME)
                .keySchema(b1 -> b1.attributeName("Id").keyType(KeyType.HASH))
                .attributeDefinitions(b2 -> b2.attributeName("Id").attributeType(ScalarAttributeType.S)));
        dynamoDbClientV2.waiter().waitUntilTableExists(b -> b.tableName(TABLE_NAME));
    }

    public void deserializationDiffs(){

        DescribeTableResponse v2Response = dynamoDbClientV2.describeTable(builder -> builder.tableName(TABLE_NAME));
        // V2 provides has* methods on model objects for list/map members. No null check needed.
        LOGGER.info( String.valueOf(v2Response.table().hasGlobalSecondaryIndexes()) );
        LOGGER.info( String.valueOf(v2Response.table().globalSecondaryIndexes().isEmpty()) );
        // V2 deserialize to an empty collection.
        LOGGER.info(v2Response.table().globalSecondaryIndexes().toString());

        // V1 deserialize to null.
        DescribeTableResult v1Result = dynamoDbClientV1.describeTable(new DescribeTableRequest(TABLE_NAME));
        if (v1Result.getTable().getGlobalSecondaryIndexes() != null){
            LOGGER.info(v1Result.getTable().getGlobalSecondaryIndexes().toString());
        } else {
            LOGGER.info("The list of global secondary indexes returned by the V1 call is <null>");
        }
    }

    public void deleteTable(){
        dynamoDbClientV2.deleteTable(b -> b.tableName(TABLE_NAME));
        dynamoDbClientV2.waiter().waitUntilTableNotExists(b -> b.tableName(TABLE_NAME));
    }
}
```

V1 和 V2 用戶端中 `describeTable`方法的 JSON `GlobalSecondaryIndexes` 回應不包含屬性：

```
{
  "Table": {
    "AttributeDefinitions": [
      {
        "AttributeName": "Id",
        "AttributeType": "S"
      }
    ],
    "BillingModeSummary": {
      "BillingMode": "PAY_PER_REQUEST",
      "LastUpdateToPayPerRequestDateTime": ...
    },
    "CreationDateTime": ...,
    "DeletionProtectionEnabled": false,
    "ItemCount": 0,
    "KeySchema": [
      {
        "AttributeName": "Id",
        "KeyType": "HASH"
      }
    ],
    "ProvisionedThroughput": {
      "NumberOfDecreasesToday": 0,
      "ReadCapacityUnits": 0,
      "WriteCapacityUnits": 0 
    },
    "TableArn": "arn:aws:dynamodb:us-east-1:11111111111:table/DeserializationTable-...",
    "TableId": "...",
    "TableName": "DeserializationTable-...",
    "TableSizeBytes": 0,
    "TableStatus": "ACTIVE",
    "TableThroughputModeSummary": {
      "LastUpdateToPayPerRequestDateTime": ...,
      "TableThroughputMode": "PAY_PER_REQUEST"
    },
    "WarmThroughput": {
      "ReadUnitsPerSecond": 12000,
      "Status": "ACTIVE",
      "WriteUnitsPerSecond": 4000
    }
  }
}
```

# 例外變更
<a name="migration-exception-changes"></a>

例外類別名稱、結構及其關係已變更。 `software.amazon.awssdk.core.exception.SdkException`是所有其他例外狀況延伸的新基本`Exception`類別。

此表是例外類別名稱變更的對應。


| 1.x | 2.x | 
| --- | --- | 
|   `com.amazonaws.SdkBaseException` `com.amazonaws.AmazonClientException`   |   `software.amazon.awssdk.core.exception.SdkException`   | 
|   `com.amazonaws.SdkClientException`   |   `software.amazon.awssdk.core.exception.SdkClientException`   | 
|   `com.amazonaws.AmazonServiceException`   |   `software.amazon.awssdk.awscore.exception.AwsServiceException`   | 

下表對應 1.x 和 2.x 版之間例外類別的方法。


| 1.x | 2.x | 
| --- | --- | 
|   `AmazonServiceException.getRequestId`   |   `SdkServiceException.requestId`   | 
|   `AmazonServiceException.getServiceName`   |   `AwsServiceException.awsErrorDetails().serviceName`   | 
|   `AmazonServiceException.getErrorCode`   |   `AwsServiceException.awsErrorDetails().errorCode`   | 
|   `AmazonServiceException.getErrorMessage`   |   `AwsServiceException.awsErrorDetails().errorMessage`   | 
|   `AmazonServiceException.getStatusCode`   |   `AwsServiceException.awsErrorDetails().sdkHttpResponse().statusCode`   | 
|   `AmazonServiceException.getHttpHeaders`   |   `AwsServiceException.awsErrorDetails().sdkHttpResponse().headers`   | 
|   `AmazonServiceException.rawResponse`   |   `AwsServiceException.awsErrorDetails().rawResponse`   | 

# 服務特定的變更
<a name="migration-service-changes"></a>

## Amazon S3 變更
<a name="s3-operations-name"></a>

適用於 Java 的 SDK 2.x 預設會停用匿名存取。因此，您必須使用 啟用匿名存取`AnonymousCredentialsProvider`。

### 操作名稱變更
<a name="s3-op-name-changes"></a>

 Amazon S3 用戶端的許多操作名稱在 適用於 Java 的 AWS SDK 2.x 中已變更。在 1.x 版中， Amazon S3 用戶端不會直接從服務 API 產生。這會造成開發套件操作與服務 API 之間的不一致。在 2.x 版中，我們現在會產生 Amazon S3 用戶端，以更符合 服務 API。

下表顯示兩個版本中的操作名稱。


**Amazon S3 操作名稱**  

| 1.x | 2.x | 
| --- | --- | 
| abortMultipartUpload | abortMultipartUpload | 
| changeObjectStorageClass  | copyObject | 
| completeMultipartUpload  | completeMultipartUpload | 
| copyObject | copyObject | 
| copyPart | uploadPartCopy | 
| createBucket | createBucket | 
| deleteBucket | deleteBucket | 
| deleteBucketAnalyticsConfiguration | deleteBucketAnalyticsConfiguration | 
| deleteBucketCrossOriginConfiguration | deleteBucketCors | 
| deleteBucketEncryption | deleteBucketEncryption | 
| deleteBucketInventoryConfiguration | deleteBucketInventoryConfiguration | 
| deleteBucketLifecycleConfiguration | deleteBucketLifecycle | 
| deleteBucketMetricsConfiguration | deleteBucketMetricsConfiguration | 
| deleteBucketPolicy | deleteBucketPolicy | 
| deleteBucketReplicationConfiguration | deleteBucketReplication | 
| deleteBucketTaggingConfiguration | deleteBucketTagging | 
| deleteBucketWebsiteConfiguration | deleteBucketWebsite | 
| deleteObject | deleteObject | 
| deleteObjectTagging | deleteObjectTagging | 
| deleteObjects | deleteObjects | 
| deleteVersion | deleteObject | 
| disableRequesterPays | putBucketRequestPayment | 
| doesBucketExist | headBucket | 
| doesBucketExistV2 | headBucket | 
| doesObjectExist | headObject | 
| enableRequesterPays | putBucketRequestPayment | 
| generatePresignedUrl | [S3Presigner](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/presigner/S3Presigner.html) | 
| getBucketAccelerateConfiguration | getBucketAccelerateConfiguration | 
| getBucketAcl | getBucketAcl | 
| getBucketAnalyticsConfiguration | getBucketAnalyticsConfiguration | 
| getBucketCrossOriginConfiguration | getBucketCors | 
| getBucketEncryption | getBucketEncryption | 
| getBucketInventoryConfiguration | getBucketInventoryConfiguration | 
| getBucketLifecycleConfiguration | getBucketLifecycle 或 getBucketLifecycleConfiguration | 
| getBucketLocation | getBucketLocation | 
| getBucketLoggingConfiguration | getBucketLogging | 
| getBucketMetricsConfiguration | getBucketMetricsConfiguration | 
| getBucketNotificationConfiguration | getBucketNotification 或 getBucketNotificationConfiguration | 
| getBucketPolicy | getBucketPolicy | 
| getBucketReplicationConfiguration | getBucketReplication | 
| getBucketTaggingConfiguration | getBucketTagging | 
| getBucketVersioningConfiguration | getBucketVersioning | 
| getBucketWebsiteConfiguration | getBucketWebsite | 
| getObject | getObject | 
| getObjectAcl | getObjectAcl | 
| getObjectAsString | getObjectAsBytes().asUtf8String | 
| getObjectMetadata | headObject | 
| getObjectTagging | getObjectTagging | 
| getResourceUrl | [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Utilities.html#getUrl(java.util.function.Consumer)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Utilities.html#getUrl(java.util.function.Consumer)) | 
| getS3AccountOwner | listBuckets | 
| getUrl | [S3Utilities\$1getUrl](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Utilities.html#getUrl(java.util.function.Consumer)) | 
| headBucket | headBucket | 
| initiateMultipartUpload | createMultipartUpload | 
| isRequesterPaysEnabled | getBucketRequestPayment | 
| listBucketAnalyticsConfigurations | listBucketAnalyticsConfigurations | 
| listBucketInventoryConfigurations | listBucketInventoryConfigurations | 
| listBucketMetricsConfigurations | listBucketMetricsConfigurations | 
| listBuckets | listBuckets | 
| listMultipartUploads | listMultipartUploads | 
| listNextBatchOfObjects | listObjectsV2Paginator | 
| listNextBatchOfVersions | listObjectVersionsPaginator | 
| listObjects | listObjects | 
| listObjectsV2 | listObjectsV2 | 
| listParts | listParts | 
| listVersions | listObjectVersions | 
| putObject | putObject | 
| restoreObject | restoreObject | 
| restoreObjectV2 | restoreObject | 
| selectObjectContent | selectObjectContent | 
| setBucketAccelerateConfiguration | putBucketAccelerateConfiguration | 
| setBucketAcl | putBucketAcl | 
| setBucketAnalyticsConfiguration | putBucketAnalyticsConfiguration | 
| setBucketCrossOriginConfiguration | putBucketCors | 
| setBucketEncryption | putBucketEncryption | 
| setBucketInventoryConfiguration | putBucketInventoryConfiguration | 
| setBucketLifecycleConfiguration | putBucketLifecycle 或 putBucketLifecycleConfiguration | 
| setBucketLoggingConfiguration | putBucketLogging | 
| setBucketMetricsConfiguration | putBucketMetricsConfiguration | 
| setBucketNotificationConfiguration | putBucketNotification 或 putBucketNotificationConfiguration | 
| setBucketPolicy | putBucketPolicy | 
| setBucketReplicationConfiguration | putBucketReplication | 
| setBucketTaggingConfiguration | putBucketTagging | 
| setBucketVersioningConfiguration | putBucketVersioning | 
| setBucketWebsiteConfiguration | putBucketWebsite | 
| setObjectAcl | putObjectAcl | 
| setObjectRedirectLocation | copyObject | 
| setObjectTagging | putObjectTagging | 
| uploadPart | uploadPart | 

## Amazon SNS 變更
<a name="sns-changes"></a>

SNS 用戶端無法再存取其設定為存取之區域以外的區域中的 SNS 主題。

## Amazon SQS 變更
<a name="sqs-changes"></a>

SQS 用戶端無法再存取其設定為存取之區域以外的區域中的 SQS 佇列。

## Amazon RDS 變更
<a name="rds-changes"></a>

適用於 Java 的 SDK 2.x 使用 `RdsUtilities#generateAuthenticationToken`取代 1.x `RdsIamAuthTokenGenerator`中的 類別。

# 使用 Amazon S3 從 第 1 版變更為 第 2 版 適用於 Java 的 AWS SDK
<a name="migration-s3"></a>

為 S3 用戶端 AWS SDK for Java 2.x 引入重大變更，包括新的套件結構、更新的類別名稱和修訂後的方法簽章。雖然許多方法都可以使用遷移[工具](migration-tool.md)從 V1 自動遷移到 V2，但有些方法需要手動遷移，例如 `listNextBatchOfObjects`和 `selectObjectContent`。此外，V2 會將 `AccessControlList`和 等特定 V1 類別取代`CannedAccessControlList`為新的實作。

**Topics**
+ [

# 第 1 版和第 2 版之間的 S3 用戶端差異 適用於 Java 的 AWS SDK
](migration-s3-client.md)
+ [

# 將 Transfer Manager 從 第 1 版遷移至 第 2 版 適用於 Java 的 AWS SDK
](migration-s3-transfer-manager.md)
+ [

# 從第 1 版剖析 Amazon S3 URIs 到第 2 版的變更
](migration-s3-uri-parser.md)
+ [

# S3 事件通知 API 從第 1 版變更為第 2 版
](migration-s3-event-notification.md)

# 第 1 版和第 2 版之間的 S3 用戶端差異 適用於 Java 的 AWS SDK
<a name="migration-s3-client"></a>

在本主題中，適用於 Java 的 SDK 第 1 版和第 2 版中的 S3 用戶端之間的差異，是由[遷移工具](migration-tool.md)如何自動化遷移所組織。該工具支援將大多數方法從 V1 遷移到 V2，但某些方法需要手動遷移。除了 S3 用戶端方法之外，某些 S3 V1 類別沒有直接 V2 對等項目，要求您手動遷移它們。

**Contents**
+ [

## 遷移工具支援的範例 V1 方法
](#methods-tool-migration)
  + [

### `putObject`
](#V1-V2-putobject)
  + [

### `getObject`
](#V1-V2-getobject)
+ [

## 需要手動遷移的 V1 方法
](#s3-methods-manual-migration)
  + [`getObject` 使用 `S3ObjectId`](#V1s-getObject-using-V1s-S3ObjectId)
  + [`getETag` 使用 `ObjectMetadata`](#V1s-ObjectMetadata-using-V1s-getETag)
  + [`listNextBatchOfObjects`](#V1-listNextBatchOfObjects)
  + [`listNextBatchOfVersions`](#V1-listNextBatchOfVersions)
  + [

### `selectObjectContent`
](#V1-selectObjectContent)
  + [`setBucketAcl`](#V1-setBucketAcl)
  + [`setObjectAcl`](#V1-setObjectAcl)
  + [`initiateMultipartUpload`](#V1-initiateMultipartUpload)
    + [

#### 遷移範例
](#V1-initiateMultipartUpload-migration-ex)
    + [

#### 實作差異
](#V1-initiateMultipartUpload-impl-diffs)
  + [`setRegion`](#V1-setRegion)
  + [`setS3ClientOptions(S3ClientOptions clientOptions)`](#V1-setS3ClientOptions)
  + [`setBucketLoggingConfiguration`](#V1-setBucketLoggingConfiguration)
  + [`setBucketLifecycleConfiguration`](#V1-setBucketLifecycleConfiguration)
  + [`setBucketTaggingConfiguration`](#V1-setBucketTaggingConfiguration)
+ [

## 需要手動遷移的 V1 類別
](#s3-classes-manual-migration)
  + [`AccessControlList`](#V1-AccessControlList)
  + [`CannedAccessControlList`](#V1-CannedAccessControlList)
  + [`BucketNotificationConfiguration`](#V1-BucketNotificationConfiguration)
  + [`MultiFactorAuthentication`](#V1-MultifactorAuthentication)

## 遷移工具支援的範例 V1 方法
<a name="methods-tool-migration"></a>

遷移工具會自動將大多數方法從 V1 遷移至 V2。`putObject` 和 `getObject`方法有兩個範例。

### `putObject`
<a name="V1-V2-putobject"></a>

```
// SDK V1
s3Client.putObject("amzn-s3-demo-bucket", "my-key", "Hello World!");


// SDK V2
s3Client.putObject(req -> req 
    .bucket("amzn-s3-demo-bucket") 
    .key("my-key"), 
    RequestBody.fromString("Hello World!"));
```

### `getObject`
<a name="V1-V2-getobject"></a>

```
// SDK V1
S3Object object = s3Client.getObject("amzn-s3-demo-bucket", "my-key");
InputStream content = object.getObjectContent();


// SDK V2
ResponseInputStream<GetObjectResponse> response = s3Client.getObject(req -> req 
    .bucket("amzn-s3-demo-bucket") 
    .key("my-key"));
```

## 需要手動遷移的 V1 方法
<a name="s3-methods-manual-migration"></a>

您需要手動遷移下列 V1 S3 用戶端方法。當您使用遷移工具時，您會在引導您前往本主題的 V2 輸出 Java 檔案中看到註解。

### V1 `getObject`使用 V1 `S3ObjectId`到 V2 的 `GetObjectRequest.builder()`
<a name="V1s-getObject-using-V1s-S3ObjectId"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
        .withRegion(Regions.US_WEST_2)
        .build();

S3ObjectId s3ObjectId = new S3ObjectId(
    "amzn-s3-demo-bucket",
    "object-key",
    "abc123version" 
);

GetObjectRequest getRequest= new GetObjectRequest(s3ObjectId);
S3Object s3ObjectVersioned = s3Client.getObject(getRequest);


// SDK V2
// V2 does not include a 'S3ObjectId' class. V2 uses the request builder pattern 
// to supply the bucket, key, and version parameters.
S3Client s3Client = S3Client.builder()
    .region(Region.US_WEST_2)
    .build();

GetObjectRequest getRequest = GetObjectRequest.builder()
    .bucket("amzn-s3-demo-bucket")
    .key("object-key")
    .versionId("abc123version")
    .build();

ResponseInputStream<GetObjectResponse> response = s3Client.getObject(getRequest);
```

### V1 `getETag()`使用 V1 `ObjectMetadata`到 V2 的 `GetObjectResponse.eTag()`
<a name="V1s-ObjectMetadata-using-V1s-getETag"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.US_WEST_2)
    .build();

S3Object object = s3ClientV1.getObject("amzn-s3-demo-bucket", "my-key");

// Double quotes are removed by the S3 client.
System.out.println(object.getObjectMetadata().getETag());

// SDK V2
S3Client s3ClientV2 = S3Client.builder()
        .region(Region.US_WEST_2)
        .build();

ResponseInputStream<GetObjectResponse> response = s3ClientV2.getObject(
        req -> req.bucket("amzn-s3-demo-bucket").key("my-key"));

// Double quotes are *NOT* removed. This is the unchanged ETag value as S3 sent it.
System.out.println(response.response().eTag());
```

### V1 `listNextBatchOfObjects`到 V2 的 `listObjectsV2Paginator`
<a name="V1-listNextBatchOfObjects"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.US_WEST_2)
    .build();

ObjectListing objectListing = s3ClientV1.listObjects("bucket-name");
while (objectListing.isTruncated()) {
    objectListing = s3ClientV1.listNextBatchOfObjects(objectListing);
    for (S3ObjectSummary summary : objectListing.getObjectSummaries()) {
        System.out.println(summary.getKey());
    }
}


// SDK V2
S3Client s3ClientV2 = S3Client.builder()
    .region(Region.US_WEST_2)
    .build();

ListObjectsV2Request request = ListObjectsV2Request.builder()
    .bucket("bucket-name")
    .build();

// V2 returns a paginator.
ListObjectsV2Iterable responses = s3Client.listObjectsV2Paginator(request);

for (ListObjectsV2Response page : responses) {
    page.contents().forEach(content -> {
        System.out.println(content.key());
    });
}
```

### V1 `listNextBatchOfVersions`到 V2 的 `listObjectVersionsPaginator`
<a name="V1-listNextBatchOfVersions"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.US_WEST_2)
    .build();

VersionListing versionListing = s3ClientV1.listVersions("bucket-name", "prefix");
while (versionListing.isTruncated()) {
    versionListing = s3ClientV1.listNextBatchOfVersions(versionListing);
    for (S3VersionSummary version : versionListing.getVersionSummaries()) {
        System.out.println(version.getKey() + " " + version.getVersionId());
    }
}


// SDK V2
S3Client s3ClientV2 = S3Client.builder()
    .region(Region.US_WEST_2)
    .build();

ListObjectVersionsRequest request = ListObjectVersionsRequest.builder()
    .bucket("bucket-name")
    .prefix("prefix")
    .build();

// V2 returns a paginator.
ListObjectVersionsIterable responses = s3ClientV2.listObjectVersionsPaginator(request);

for (ListObjectVersionsResponse page : responses) {
    page.versions().forEach(version -> {
        System.out.println(version.key() + " " + version.versionId());
    });
}
```

### `selectObjectContent`
<a name="V1-selectObjectContent"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.US_WEST_2)
    .build();

SelectObjectContentRequest request = new SelectObjectContentRequest()
    .withBucket("bucket-name")
    .withKey("object-key")
    .withExpression("select * from S3Object")
    .withExpressionType(ExpressionType.SQL)
 

SelectObjectContentResult result = s3ClientV1.selectObjectContent(request);
InputStream resultInputStream = result.getPayload().getRecordsInputStream();


// SDK V2
// In V2, 'selectObjectContent()' is available only on the S3AsyncClient. 
// V2 handles responses using an event-based 'SelectObjectContentEventStream'.
S3AsyncClient s3ClientV2 = S3AsyncClient.builder()
    .region(Region.US_WEST_2)
    .build();

SelectObjectContentRequest request = SelectObjectContentRequest.builder()
    .bucket("bucket-name")
    .key("object-key")
    .expression("select * from S3Object")
    .expressionType(ExpressionType.SQL)
    .build();
    
SelectObjectContentResponseHandler handler = new SelectObjectContentResponseHandler() {
    // Implement the required abstract methods such as 'onEventStream()'.
};

CompletableFuture<Void> future = s3ClientV2.selectObjectContent(request, handler);
// The 'SelectObjectContentResponseHandler' implementation processes the results.
```

### 上 V1 `setBucketAcl`到 V2 的 `acl`方法 `PutBucketAclRequest.builder()`
<a name="V1-setBucketAcl"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.US_WEST_2)
    .build();

AccessControlList acl = new AccessControlList();
acl.grantPermission(GroupGrantee.AllUsers, Permission.Read);
s3ClientV1.setBucketAcl("bucket-name", acl);


// SDK V2
S3Client s3ClientV2 = S3Client.builder()
    .region(Region.US_WEST_2)
    .build();

PutBucketAclRequest request = PutBucketAclRequest.builder()
    .bucket("bucket-name")
    .acl(BucketCannedACL.PRIVATE)
    .build();

s3ClientV2.putBucketAcl(request);
```

### 上 V1 `setObjectAcl`到 V2 的 `acl`方法 `PutObjectAclRequest.builder()`
<a name="V1-setObjectAcl"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.US_WEST_2)
    .build();

AccessControlList acl = new AccessControlList();
acl.grantPermission(GroupGrantee.AllUsers, Permission.Read);
s3ClientV1.setObjectAcl("bucket-name", "object-key", acl);


// SDK V2
S3Client s3ClientV2 = S3Client.builder()
    .region(Region.US_WEST_2)
    .build();

PutObjectAclRequest request = PutObjectAclRequest.builder()
    .bucket("bucket-name")
    .key("object-key")
    .acl(ObjectCannedACL.PRIVATE)
    .build();

s3ClientV2.putObjectAcl(request);
```

### V1 `initiateMultipartUpload`到 V2 的 `createMultipartUpload`
<a name="V1-initiateMultipartUpload"></a>

#### 遷移範例
<a name="V1-initiateMultipartUpload-migration-ex"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.US_WEST_2)
    .build();
    
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("application/zip");
metadata.addUserMetadata("mykey", "myvalue");

InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(
    "bucket-name", 
    "object-key",
    metadata
);

InitiateMultipartUploadResult initResponse = s3ClientV1.initiateMultipartUpload(initRequest);
String uploadId = initResponse.getUploadId();


// SDK V2
// V1 uses ObjectMetadata methods, whereas V2 uses a simple Map.
S3Client s3ClientV2 = S3Client.builder()
    .region(Region.US_WEST_2)
    .build();

CreateMultipartUploadRequest createMultipartRequest = CreateMultipartUploadRequest.builder() 
    .bucket("amzn-s3-demo-bucket") 
    .key("object-key") 
    .contentType("application/zip") 
    .metadata(Collections.singletonMap("mykey", "myvalue"))
    .build();

CreateMultipartUploadResponse response = s3ClientV2.createMultipartUpload(createMultipartRequest);
String uploadId = response.uploadId();
```

#### 實作差異
<a name="V1-initiateMultipartUpload-impl-diffs"></a>

下列方法的預設`Content-Type`標頭值會有所不同，如下表所示。


****  

| SDK 版本 | Method | `Content-Type` 預設值 | 
| --- | --- | --- | 
| 第 1 版 | [initiateMultipartUpload](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#initiateMultipartUpload-com.amazonaws.services.s3.model.InitiateMultipartUploadRequest-) | application/octet-stream | 
| 版本 2 | [createMultipartUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html#createMultipartUpload(software.amazon.awssdk.services.s3.model.CreateMultipartUploadRequest)) | binary/octet-stream | 

### 用戶端建置器上 V1 `setRegion`到 V2 的 `region`方法
<a name="V1-setRegion"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard().build();
s3ClientV1.setRegion(Region.getRegion(Regions.US_WEST_2));


// SDK V2
S3Client s3ClientV2 = S3Client.builder()
    .region(Region.US_WEST_2)
    .build();
```

### V1 的 `setS3ClientOptions(S3ClientOptions clientOptions)`
<a name="V1-setS3ClientOptions"></a>

V2 在用戶端建置器上提供方法來設定選項，而不是搭配 `setS3ClientOptions`方法使用單一`S3ClientOptions`物件。

### V1 `setBucketLoggingConfiguration`到 V2 的 `putBucketLogging`
<a name="V1-setBucketLoggingConfiguration"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.US_WEST_2)
    .build();

BucketLoggingConfiguration loggingConfig = new BucketLoggingConfiguration();
loggingConfig.setDestinationBucketName("log-bucket");

SetBucketLoggingConfigurationRequest request = new SetBucketLoggingConfigurationRequest(
    "amzn-s3-demo-source-bucket",
    loggingConfig
);

s3ClientV1.setBucketLoggingConfiguration(request);


// SDK V2
// In V2, V1's 'BucketLoggingConfiguration' is replaced by 'BucketLoggingStatus' 
// and 'LoggingEnabled'.
S3Client s3ClientV2 = S3Client.builder()
    .region(Region.US_WEST_2)
    .build();

LoggingEnabled loggingEnabled = LoggingEnabled.builder()
    .targetBucket("log-bucket")
    .build();

BucketLoggingStatus loggingStatus = BucketLoggingStatus.builder()
    .loggingEnabled(loggingEnabled)
    .build();

PutBucketLoggingRequest request = PutBucketLoggingRequest.builder()
    .bucket("amzn-s3-demo-source-bucket")
    .bucketLoggingStatus(loggingStatus)
    .build();

s3ClientV2.putBucketLogging(request);
```

### V1 `setBucketLifecycleConfiguration`到 V2 的 `putBucketLifecycleConfiguration`
<a name="V1-setBucketLifecycleConfiguration"></a>

```
// SDK V1
BucketLifecycleConfiguration.Rule rule = new BucketLifecycleConfiguration.Rule()
    .withId("Archive and Delete Rule")
    .withPrefix("documents/")
    .withStatus(BucketLifecycleConfiguration.ENABLED)
    .withTransitions(Arrays.asList(
        new Transition()
            .withDays(30)
            .withStorageClass(StorageClass.StandardInfrequentAccess.toString()),
        new Transition()
            .withDays(90)
            .withStorageClass(StorageClass.Glacier.toString())
    ))
    .withExpirationInDays(365);

BucketLifecycleConfiguration configuration = new BucketLifecycleConfiguration()
    .withRules(Arrays.asList(rule));

s3ClientV1.setBucketLifecycleConfiguration("amzn-s3-demo-bucket", configuration);


// SDK V2
LifecycleRule rule = LifecycleRule.builder()
    .id("Archive and Delete Rule")
    .filter(LifecycleRuleFilter.builder()
        .prefix("documents/")
        .build())
    .status(ExpirationStatus.ENABLED)
    .transitions(Arrays.asList(
        Transition.builder()
            .days(30)
            .storageClass(TransitionStorageClass.STANDARD_IA)
            .build(),
        Transition.builder()
            .days(90)
            .storageClass(TransitionStorageClass.GLACIER)
            .build()
    ))
    .expiration(LifecycleExpiration.builder()
        .days(365)
        .build())
    .build();

PutBucketLifecycleConfigurationRequest request = PutBucketLifecycleConfigurationRequest.builder()
    .bucket("amzn-s3-demo-bucket")
    .lifecycleConfiguration(BucketLifecycleConfiguration.builder()
        .rules(rule)
        .build())
    .build();

s3ClientV2.putBucketLifecycleConfiguration(request);
```

### V1 `setBucketTaggingConfiguration`到 V2 的 `putBucketTagging`
<a name="V1-setBucketTaggingConfiguration"></a>

```
// SDK V1
List<TagSet> tagsets = new ArrayList<>();
TagSet tagSet = new TagSet();
tagSet.setTag("key1", "value1");
tagSet.setTag("key2", "value2");
tagsets.add(tagSet);

BucketTaggingConfiguration bucketTaggingConfiguration = new BucketTaggingConfiguration();
bucketTaggingConfiguration.setTagSets(tagsets);

SetBucketTaggingConfigurationRequest request = new SetBucketTaggingConfigurationRequest(
    "amzn-s3-demo-bucket",
    bucketTaggingConfiguration
);

s3ClientV1.setBucketTaggingConfiguration(request);


// SDK V2
Tagging tagging = Tagging.builder()
    .tagSet(Arrays.asList(
        Tag.builder()
            .key("key1")
            .value("value1")
            .build(),
        Tag.builder()
            .key("key2")
            .value("value2")
            .build()
    ))
    .build();

PutBucketTaggingRequest request = PutBucketTaggingRequest.builder()
    .bucket("amzn-s3-demo-bucket")
    .tagging(tagging)
    .build();

s3ClientV2.putBucketTagging(request);
```

## 需要手動遷移的 V1 類別
<a name="s3-classes-manual-migration"></a>

### V1 `AccessControlList`到 V2 的 `AccessControlPolicy`
<a name="V1-AccessControlList"></a>

```
// SDK V1
AccessControlList aclV1 = new AccessControlList();
aclV1.setOwner(new Owner("owner-id", "owner-name"));
aclV1.grantPermission(GroupGrantee.AllUsers, Permission.Read);

// SDK V2
// To migrate from V1 to V2, replace direct 'AccessControlList' modifications with an
// 'AccessControlPolicy.builder()' that contains both owner information and grants. 
// Note that V2's approach requires building the complete permission set upfront rather than modifying permissions incrementally.
AccessControlPolicy acpV2 = AccessControlPolicy.builder()
    .owner(Owner.builder()
        .id("owner-id")
        .displayName("owner-name")
        .build())
    .grants(Arrays.asList(
         Grant.builder()
            .grantee(Grantee.builder()
                 .type(Type.GROUP)
                 .uri("http://acs.amazonaws.com/groups/global/AllUsers") 
                 .build())
             .permission(Permission.READ)
             .build()
     ))
     .build();
```

### V1 的 V2 `CannedAccessControlList` 列舉`BucketCannedACL`和`ObjectCannedACL`列舉
<a name="V1-CannedAccessControlList"></a>

```
// SDK V1
// In V1, 'CannedAccessControlList' is an enumeration of predefined ACLs.
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard().build();

// Creating a bucket.
s3ClientV1.setBucketAcl("bucket-name", CannedAccessControlList.PublicRead);

// Creating an object.
PutObjectRequest putObjectRequest = new PutObjectRequest("bucket-name", "object-key", file)
    .withCannedAcl(CannedAccessControlList.PublicRead);
s3ClientV1.putObject(putObjectRequest);


// SDK V2
// V2 replaces V1's 'CannedAccessControlList' with 'BucketCannedACL' for buckets and 'ObjectCannedACL' for objects.
S3Client s3ClientV2 = S3Client.builder().build();

// Creating a bucket.
PutBucketAclRequest bucketRequest = PutBucketAclRequest.builder()
    .bucket("bucket-name")
    .acl(BucketCannedACL.PRIVATE)
    .build();
s3ClientV2.putBucketAcl(bucketRequest);

// Creating an object.
PutObjectRequest objectRequest = PutObjectRequest.builder()
    .bucket("bucket-name")
    .key("object-key")
    .acl(ObjectCannedACL.PUBLIC_READ)
    .build();
s3ClientV2.putObject(objectRequest, RequestBody.fromFile(file));
```

### V1 `BucketNotificationConfiguration`到 V2 的 `NotificationConfiguration`
<a name="V1-BucketNotificationConfiguration"></a>

```
//SDK V1
BucketNotificationConfiguration notificationConfig = new BucketNotificationConfiguration();

// Adding configurations by name
notificationConfig.addConfiguration("lambdaConfig", 
    new LambdaConfiguration("arn:aws:lambda:function", "s3:ObjectCreated:"));

notificationConfig.addConfiguration("topicConfig",
    new TopicConfiguration("arn:aws:sns:topic", "s3:ObjectRemoved:"));

notificationConfig.addConfiguration("queueConfig",
    new QueueConfiguration("arn:aws:sqs:queue", "s3:ObjectRestore:*"));

s3Client.setBucketNotificationConfiguration("bucket", notificationConfig);


// SDK V2
// In V2, V1's BucketNotificationConfiguration is renamed to NotificationConfiguration. 
// V2 contains no common abstract class for LambdaFunction/Topic/Queue configurations.
NotificationConfiguration notificationConfig = NotificationConfiguration.builder()
    .lambdaFunctionConfigurations(
        LambdaFunctionConfiguration.builder()
            .lambdaFunctionArn("arn:aws:lambda:function")
            .events(Event.valueOf("s3:ObjectCreated:"))
            .build())
    .topicConfigurations(
        TopicConfiguration.builder()
            .topicArn("arn:aws:sns:topic")
            .events(Event.valueOf("s3:ObjectRemoved:"))
            .build())
    .queueConfigurations(
        QueueConfiguration.builder()
            .queueArn("arn:aws:sqs:queue")
            .events(Event.valueOf("s3:ObjectRestore:*"))
            .build())
    .build();

s3Client.putBucketNotificationConfiguration(req -> req
    .bucket("bucket")
    .notificationConfiguration(notificationConfig));
```

### 請求建置器上 V1 `MultiFactorAuthentication` 到 V2 `mfa`的方法
<a name="V1-MultifactorAuthentication"></a>

```
// SDK V1
AmazonS3 s3ClientV1 = AmazonS3ClientBuilder.standard()
    .withRegion(Regions.US_WEST_2)
    .build();

BucketVersioningConfiguration versioningConfig = new BucketVersioningConfiguration()
    .withStatus(BucketVersioningConfiguration.ENABLED);

// Create an MFA configuration object.
MultiFactorAuthentication mfa = new MultiFactorAuthentication(
    "arn:aws:iam::1234567890:mfa/user",
    "123456"
);

// Create the request object.
SetBucketVersioningConfigurationRequest request = new SetBucketVersioningConfigurationRequest(
    "bucket-name",
    versioningConfig,
    mfa
);

// Send the request.
s3ClientV1.setBucketVersioningConfiguration(request);


// SDK V2
// V2 replaces V1's MultiFactorAuthentication POJO with parameters you set on the request builder.
S3Client s3ClientV2 = S3Client.builder()
    .region(Region.US_WEST_2)
    .build();

PutBucketVersioningRequest request = PutBucketVersioningRequest.builder()
    .bucket("bucket-name")
    .versioningConfiguration(VersioningConfiguration.builder()
        .status(BucketVersioningStatus.ENABLED)
        .build())
    .mfa("arn:aws:iam::1234567890:mfa/user 123456")  // Single method takes both MFA erial number and token.
    .build();

s3ClientV2.putBucketVersioning(request);
```

# 將 Transfer Manager 從 第 1 版遷移至 第 2 版 適用於 Java 的 AWS SDK
<a name="migration-s3-transfer-manager"></a>

此遷移指南涵蓋 Transfer Manager v1 和 S3 Transfer Manager v2 之間的主要差異，包括建構函數變更、方法映射和常見操作的程式碼範例。檢閱這些差異後，您可以成功遷移現有的 Transfer Manager 程式碼，以利用 v2 中改善的效能和非同步操作。

**關於 AWS SDK 遷移工具**  
 適用於 Java 的 AWS SDK 提供自動化[遷移工具](migration-tool.md)，可將大部分 v1 Transfer Manager API 遷移至 v2。不過，遷移工具不支援數個 v1 Transfer Manager 功能。在這些情況下，您需要使用本主題中的指引手動遷移 Transfer Manager 程式碼。  
在本指南中，**遷移狀態**會顯示遷移工具是否可以自動遷移建構函數、方法或功能：  
**支援**：遷移工具可以自動轉換此程式碼
**不支援**：您需要手動遷移程式碼
即使是標記為「支援」的項目，請檢閱遷移結果並徹底測試。Transfer Manager 遷移涉及從同步操作到非同步操作的重大架構變更。

## 概觀
<a name="s3-tm-migration-overview"></a>

S3 Transfer Manager v2 會將重大變更引入 Transfer Manager API。S3 Transfer Manager v2 建立在非同步操作上，並提供更好的效能，尤其是當您使用 AWS CRT 型 Amazon S3 用戶端時。

### 主要差異
<a name="s3-tm-migration-key-differences"></a>
+ **套件**：`com.amazonaws.services.s3.transfer`→ `software.amazon.awssdk.transfer.s3`
+ **類別名稱**：`TransferManager`→ `S3TransferManager`
+ **用戶端相依性**：同步 Amazon S3 用戶端 → 非同步 Amazon S3 用戶端 (`S3AsyncClient`)
+ **架構**：同步操作 → 使用 進行非同步操作 `CompletableFuture`
+ **效能**：透過 AWS CRT 型用戶端支援增強

## 高階變更
<a name="s3-tm-migration-high-level-changes"></a>


| 面向 | V1 | V2 | 
| --- | --- | --- | 
| Maven 相依性 | aws-java-sdk-s3 | s3-transfer-manager | 
| 套件 | com.amazonaws.services.s3.transfer | software.amazon.awssdk.transfer.s3 | 
| 主要類別 | TransferManager | S3TransferManager | 
| Amazon S3 用戶端 | AmazonS3 （同步） | S3AsyncClient （非同步） | 
| 傳回類型 | 封鎖操作 | CompletableFuture<T> | 

## Maven 相依性
<a name="s3-tm-migration-dependencies"></a>


| V1 | V2 | 
| --- | --- | 
|  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>com.amazonaws</groupId><br />            <artifactId>aws-java-sdk-bom</artifactId><br />            <version>>1.12.7871</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-java-sdk-s3</artifactId><br />    </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.31.682</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>s3-transfer-manager</artifactId><br />    </dependency><br />    <!-- Optional: For enhanced performance with AWS CRT --><br />    <dependency><br />        <groupId>software.amazon.awssdk.crt</groupId><br />        <artifactId>aws-crt</artifactId><br />        <version>0.38.53</version><br />    </dependency><br /></dependencies></pre>  | 

1 [最新版本](https://central.sonatype.com/artifact/com.amazonaws/aws-java-sdk-bom)。 2 [最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。 3[最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk.crt/aws-crt)。

## 用戶端建構函數遷移
<a name="s3-tm-migration-client-constructor"></a>

### 支援的建構函數 （自動遷移）
<a name="s3-tm-migration-supported-constructors"></a>


| V1 建構函數 | V2 對等 | 遷移狀態 | 
| --- | --- | --- | 
| new TransferManager() | S3TransferManager.create() | 支援 | 
| TransferManagerBuilder. defaultTransferManager() | S3TransferManager.create() | 支援 | 
| TransferManagerBuilder. standard().build() | S3TransferManager.builder().build() | 支援 | 
| new TransferManager(AWSCredentials) | S3TransferManager.builder() .s3Client(S3AsyncClient.builder() .credentialsProvider(...).build()) .build() | 支援 | 
| new TransferManager( AWSCredentialsProvider) | S3TransferManager.builder() .s3Client(S3AsyncClient.builder() .credentialsProvider(...).build()) .build() | 支援 | 

### 不支援的建構函數 （需要手動遷移）
<a name="s3-tm-migration-unsupported-constructors"></a>


| V1 建構函數 | V2 對等 | 遷移備註 | 
| --- | --- | --- | 
| new TransferManager(AmazonS3) | 需要手動遷移 | S3AsyncClient 分別建立 | 
| new TransferManager(AmazonS3, ExecutorService) | 需要手動遷移 | 建立 S3AsyncClient並設定執行器 | 
| new TransferManager(AmazonS3, ExecutorService, boolean) | 需要手動遷移 | shutDownThreadPools 不支援 參數 | 

### 手動遷移範例
<a name="s3-tm-migration-manual-examples"></a>

**V1 程式碼：**

```
AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();
TransferManager transferManager = new TransferManager(s3Client);
```

**V2 程式碼：**

```
// Create an `S3AsyncClient` with similar configuration
S3AsyncClient s3AsyncClient = S3AsyncClient.builder()
    .credentialsProvider(DefaultCredentialsProvider.create())
    .build();

// Provide the configured `S3AsyncClient` to the S3 transfer manager builder.
S3TransferManager transferManager = S3TransferManager.builder()
    .s3Client(s3AsyncClient)
    .build();
```

## 用戶端方法遷移
<a name="s3-tm-migration-client-methods"></a>

目前，遷移工具支援基本 `copy`、`download`、、`upload``uploadDirectory`、`downloadDirectory`、 `resumeDownload`和 `resumeUpload`方法。

### 核心傳輸方法
<a name="s3-tm-migration-core-transfer-methods"></a>


| V1 方法 | V2 方法 | 傳回類型變更 | 遷移狀態 | 
| --- | --- | --- | --- | 
| upload(String, String, File) | uploadFile(UploadFileRequest) | Upload → FileUpload | 支援 | 
| upload(PutObjectRequest) | upload(UploadRequest) | Upload → Upload | 支援 | 
| download(String, String, File) | downloadFile(DownloadFileRequest) | Download → FileDownload | 支援 | 
| download(GetObjectRequest, File) | downloadFile(DownloadFileRequest) | Download → FileDownload | 支援 | 
| copy(String, String, String, String) | copy(CopyRequest) | Copy → Copy | 支援 | 
| copy(CopyObjectRequest) | copy(CopyRequest) | Copy → Copy | 支援 | 
| uploadDirectory(String, String, File, boolean) | uploadDirectory( UploadDirectoryRequest) | MultipleFileUpload → DirectoryUpload | 支援 | 
| downloadDirectory(String, String, File) | downloadDirectory( DownloadDirectoryRequest) | MultipleFileDownload → DirectoryDownload | 支援 | 

### 可繼續傳輸方法
<a name="s3-tm-migration-resumable-methods"></a>


| V1 方法 | V2 方法 | 遷移狀態 | 
| --- | --- | --- | 
| resumeUpload(PersistableUpload) | resumeUploadFile(ResumableFileUpload) | 支援 | 
| resumeDownload(PersistableDownload) | resumeDownloadFile(ResumableFileDownload) | 支援 | 

### 生命週期方法
<a name="s3-tm-migration-lifecycle-methods"></a>


| V1 方法 | V2 方法 | 遷移狀態 | 
| --- | --- | --- | 
| shutdownNow() | close() | 支援 | 
| shutdownNow(boolean) | 使用 close()方法手動調整程式碼 | 不支援 | 

### 不支援的 V1 用戶端方法
<a name="s3-tm-migration-unsupported-methods"></a>


| V1 方法 | V2 替代方案 | 備註 | 
| --- | --- | --- | 
| abortMultipartUploads(String, Date) | 使用低階 Amazon S3 用戶端 | 不支援 | 
| getAmazonS3Client() | 分別儲存參考 | 不支援；v2 中沒有 getter | 
| getConfiguration() | 分別儲存參考 | 不支援；v2 中沒有 getter | 
| uploadFileList(...) | 進行多次uploadFile()呼叫 | 不支援 | 
| copy 具有 TransferStateChangeListener 參數的方法 | 使用 TransferListener | [請參閱手動遷移範例](#tm-unsupported-client-methods-copy) | 
| download 方法搭配 S3ProgressListener 參數 | 使用 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/TransferListener.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/TransferListener.html) | [請參閱手動遷移範例](#tm-unsupported-client-methods-download) | 
|  `downloadDirectory` 具有 4 個或更多參數的方法  |  | [請參閱手動遷移範例](#tm-unsupported-client-methods-download-dir) | 
| upload 方法與 ObjectMetadataProvider 參數 | 在請求中設定中繼資料 | [請參閱手動遷移範例](#tm-unsupported-client-methods-upload) | 
| uploadDirectory 方法與 \$1Provider 參數 | 在請求中設定標籤 | [請參閱手動遷移範例](#tm-unsupported-client-methods-uploadDirectory) | 

#### `copy` 具有 `TransferStateChangeListener` 參數的方法
<a name="tm-unsupported-client-methods-copy"></a>
+ `copy(CopyObjectRequest copyObjectRequest, AmazonS3 srcS3, TransferStateChangeListener stateChangeListener)`
+ `copy(CopyObjectRequest copyObjectRequest, TransferStateChangeListener stateChangeListener)`

```
// V1 ----------------------------------------------------------------------------------------------
// Initialize source S3 client
AmazonS3 s3client = AmazonS3ClientBuilder.standard()
                .withRegion("us-west-2")
                .build();
                
// Initialize Transfer Manager
TransferManager tm = TransferManagerBuilder.standard()
                .withS3Client(srcS3)
                .build();

CopyObjectRequest copyObjectRequest = new CopyObjectRequest(
                "amzn-s3-demo-source-bucket",
                "source-key",         
                "amzn-s3-demo-destination-bucket", 
                "destination-key"    
        );

TransferStateChangeListener stateChangeListener = new TransferStateChangeListener() {
            @Override
            public void transferStateChanged(Transfer transfer, TransferState state) {
              //Implementation of the TransferStateChangeListener
            }
        };

Copy copy = tm.copy(copyObjectRequest, srcS3, stateChangeListener);


// V2 ----------------------------------------------------------------------------------------------
S3AsyncClient s3AsyncClient = S3AsyncClient.builder()
                .region(Region.US_WEST_2)          
                .build();

S3TransferManager transferManager = S3TransferManager.builder()
                .s3Client(s3AsyncClient)
                .build();

// Create transfer listener (equivalent to TransferStateChangeListener in v1)                                
TransferListener transferListener = new TransferListener() {
            @Override
            public void transferInitiated(Context.TransferInitiated context) {
               //Implementation
               System.out.println("Transfer initiated");
            }

            @Override
            public void bytesTransferred(Context.BytesTransferred context) {
                //Implementation
                System.out.println("Bytes transferred");
            }

            @Override
            public void transferComplete(Context.TransferComplete context) {
                //Implementation
                System.out.println("Transfer completed!");
            }

            @Override
            public void transferFailed(Context.TransferFailed context) {
                //Implementation
                System.out.println("Transfer failed");
            }
        };

CopyRequest copyRequest = CopyRequest.builder()
                              .copyObjectRequest(req -> req
                                  .sourceBucket("amzn-s3-demo-source-bucket")
                                  .sourceKey("source-key")
                                  .destinationBucket("amzn-s3-demo-destination-bucket")
                                  .destinationKey("destination-key")
                               )
                                .addTransferListener(transferListener) // Configure the transferListener into the request
                                .build();
  
Copy copy = transferManager.copy(copyRequest);
```

#### `download` 方法搭配 `S3ProgressListener` 參數
<a name="tm-unsupported-client-methods-download"></a>
+ `download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener)`
+ `download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener, long timeoutMillis)`
+ `download(GetObjectRequest getObjectRequest, File file, S3ProgressListener progressListener, long timeoutMillis, boolean resumeOnRetry)`

```
// V1 ----------------------------------------------------------------------------------------------
S3ProgressListener progressListener = new S3ProgressListener() {
        @Override
        public void progressChanged(com.amazonaws.event.ProgressEvent progressEvent) {
            long bytes = progressEvent.getBytesTransferred();
            ProgressEventType eventType = progressEvent.getEventType();
            // Use bytes and eventType as needed
        }

        @Override
        public void onPersistableTransfer(PersistableTransfer persistableTransfer) {

        }
    };

Download download1 = tm.download(getObjectRequest, file, progressListener); 
Download download2 = tm.download(getObjectRequest, file, progressListener, timeoutMillis)
Download download3 = tm.download(getObjectRequest, file, progressListener, timeoutMillis, true)

// V2 ----------------------------------------------------------------------------------------------
TransferListener transferListener = new TransferListener() {
    @Override
    public void transferInitiated(Context.InitializedContext context) {
        // Equivalent to ProgressEventType.TRANSFER_STARTED_EVENT
        System.out.println("Transfer initiated");
    }

    @Override
    public void bytesTransferred(Context.BytesTransferred context) {
        // Equivalent to ProgressEventType.REQUEST_BYTE_TRANSFER_EVENT
        long bytes = context.bytesTransferred();
        System.out.println("Bytes transferred: " + bytes);
    }

    @Override
    public void transferComplete(Context.TransferComplete context) {
        // Equivalent to ProgressEventType.TRANSFER_COMPLETED_EVENT
        System.out.println("Transfer completed");
    }

    @Override
    public void transferFailed(Context.TransferFailed context) {
        // Equivalent to ProgressEventType.TRANSFER_FAILED_EVENT
        System.out.println("Transfer failed: " + context.exception().getMessage());
    }
};
DownloadFileRequest downloadFileRequest = 
                         DownloadFileRequest.builder()
                             .getObjectRequest(getObjectRequest)
                             .destination(file.toPath())
                             .addTransferListener(transferListener)
                             .build();

// For download1
FileDownload download = transferManager.downloadFile(downloadFileRequest);

// For download2
CompletedFileDownload completedFileDownload = download.completionFuture()
                                                  .get(timeoutMillis, TimeUnit.MILLISECONDS);

// For download3, the v2 SDK does not have a direct equiavalent to the `resumeOnRetry` method of v1.
// If a download is interrupted, you need to start a new download request.
```

#### `downloadDirectory` 具有 4 個或更多參數的方法
<a name="tm-unsupported-client-methods-download-dir"></a>
+ `downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, boolean resumeOnRetry)`
+ `downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, boolean resumeOnRetry, KeyFilter filter)`
+ `downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, KeyFilter filter)`

```
// V1 ----------------------------------------------------------------------------------------------
KeyFilter filter = new KeyFilter() {
            @Override
            public boolean shouldInclude(S3ObjectSummary objectSummary) {
                //Filter implementation
            }
        };
MultipleFileDownload multipleFileDownload = tm.downloadDirectory(bucketName, keyPrefix, destinationDirectory, filter);

// V2 ----------------------------------------------------------------------------------------------
// The v2 SDK does not have a direct equiavalent to the `resumeOnRetry` method of v1.
// If a download is interrupted, you need to start a new download request.
DownloadFilter filter = new DownloadFilter() {
            @Override
            public boolean test(S3Object s3Object) {
                // Filter implementation.
            }
        };

DownloadDirectoryRequest downloadDirectoryRequest = 
                              DownloadDirectoryRequest.builder()
                                  .bucket(bucketName)
                                  .filter(filter)
                                  .listObjectsV2RequestTransformer(builder -> builder.prefix(keyPrefix))
                                  .destination(destinationDirectory.toPath())
                                  .build();
                                                                            
DirectoryDownload directoryDownload = transferManager.downloadDirectory(downloadDirectoryRequest);
```

#### `upload` 方法與 `ObjectMetadata` 參數
<a name="tm-unsupported-client-methods-upload"></a>
+ `upload(String bucketName, String key, InputStream input, ObjectMetadata objectMetadata)`

```
// V1 ----------------------------------------------------------------------------------------------ObjectMetadata metadata = new ObjectMetadata();
ObjectMetadata metadata = new ObjectMetadata();

metadata.setContentType("text/plain");        // System-defined metadata
metadata.setContentLength(22L);               // System-defined metadata
metadata.addUserMetadata("myKey", "myValue"); // User-defined metadata

PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, metadata);

Upload upload = transferManager.upload("amzn-s3-demo-bucket", "my-key", inputStream, metadata);

// V2 ----------------------------------------------------------------------------------------------
/* When you use an InputStream to upload in V2, you should specify the content length 
   and use `RequestBody.fromInputStream()`. 
   If you don't provide the content length, the entire stream will be buffered in memory. 
   If you can't determine the content length, we recommend using the CRT-based S3 client.
*/
Map<String, String> userMetadata = new HashMap<>();
userMetadata.put("x-amz-meta-myKey", "myValue");

PutObjectRequest putObjectRequest = 
                        PutObjectRequest.builder()
                            .bucket("amzn-s3-demo-bucket1")
                            .key("k")
                            .contentType("text/plain") //System-defined metadata usually has separate methods in the builder.
                            .contentLength(22L)
                            .metadata(userMetadata) //metadata() is only for user-defined metadata.
                            .build();

UploadRequest uploadRequest = 
                        UploadRequest.builder()
                            .putObjectRequest(putObjectRequest)
                            .requestBody(AsyncRequestBody.fromInputStream(stream, 22L, executor))
                            .build();
                                                   
transferManager.upload(uploadRequest).completionFuture().join();
```

#### `uploadDirectory` 使用 `ObjectMetadataProvider` 參數
<a name="tm-unsupported-client-methods-uploadDirectory"></a>
+ `uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider)`
+ `uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider, ObjectTaggingProvider taggingProvider)`
+ `uploadDirectory(String bucketName, String virtualDirectoryKeyPrefix, File directory, boolean includeSubdirectories, ObjectMetadataProvider metadataProvider, ObjectTaggingProvider taggingProvider, ObjectCannedAclProvider cannedAclProvider)`

```
// V1 ----------------------------------------------------------------------------------------------
tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider)
tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider, taggingProvider)
tm.uploadDirectory(bucketName, virtualDirectoryKeyPrefix, directory, includeSubdirectories, metadataProvider, taggingProvider, cannedAclProvider)

// V2 ----------------------------------------------------------------------------------------------
UploadDirectoryRequest request = UploadDirectoryRequest.builder()
                                  .bucket(bucketName)
                                  .s3Prefix(virtualDirectoryKeyPrefix)
                                  .source(directory.toPath())
                                  .maxDepth(includeSubdirectories ? Integer.MAX_VALUE : 1)
                                  .uploadFileRequestTransformer(builder -> {
                                      // 1.Replace `ObjectMetadataProvider`, `ObjectTaggingProvider`, and `ObjectCannedAclProvider` with an
                                        // `UploadFileRequestTransformer` that can combine the functionality of all three *Provider implementations.
                                        // 2. Convert your v1 `ObjectMetadata` to v2 `PutObjectRequest` parameters.
                                        // 3. Convert your v1 `ObjectTagging` to v2 `Tagging`.
                                        // 4. Convert your v1 `CannedAccessControlList` to v2 `ObjectCannedACL`.
                                  })
                                  .build();
        
DirectoryUpload directoryUpload = transferManager.uploadDirectory(request);
```

## 模型物件遷移
<a name="s3-tm-migration-model-objects"></a>

在 中 AWS SDK for Java 2.x，許多`TransferManager`模型物件已重新設計，不再支援 v1 模型物件中可用的多種 getter 和 setter 方法。

在 v2 中，您可以使用 `CompletableFuture<T>`類別在傳輸完成時執行動作，無論是成功還是例外。如有需要，您可以使用 `join()`方法等待完成。

### 核心傳輸物件
<a name="s3-tm-migration-core-transfer-objects"></a>


| V1 類別 | V2 類別 | 遷移狀態 | 
| --- | --- | --- | 
| TransferManager | S3TransferManager | 支援 | 
| TransferManagerBuilder | S3TransferManager.Builder | 支援 | 
| Transfer | Transfer | 支援 | 
| AbortableTransfer | Transfer | 支援 （無個別類別） | 
| Copy | Copy | 支援 | 
| Download | FileDownload | 支援 | 
| Upload | Upload / FileUpload | 支援 | 
| MultipleFileDownload | DirectoryDownload | 支援 | 
| MultipleFileUpload | DirectoryUpload | 支援 | 

### 持久性物件
<a name="s3-tm-migration-persistence-objects"></a>


| V1 類別 | V2 類別 | 遷移狀態 | 
| --- | --- | --- | 
| PersistableDownload | ResumableFileDownload | 支援 | 
| PersistableUpload | ResumableFileUpload | 支援 | 
| PersistableTransfer | ResumableTransfer | 支援 | 
| PauseResult<T> | 直接可繼續物件 | 不支援 | 

### 結果物件
<a name="s3-tm-migration-result-objects"></a>


| V1 類別 | V2 類別 | 遷移狀態 | 
| --- | --- | --- | 
| CopyResult | CompletedCopy | 支援 | 
| UploadResult | CompletedUpload | 支援 | 

### 組態物件
<a name="s3-tm-migration-configuration-objects"></a>


| V1 類別 | V2 類別 | 遷移狀態 | 
| --- | --- | --- | 
| TransferManagerConfiguration | MultipartConfiguration （在 Amazon S3 用戶端上） | 支援 | 
| TransferProgress | TransferProgress \$1 TransferProgressSnapshot | 支援 | 
| KeyFilter | DownloadFilter | 支援 | 

### 不支援的物件
<a name="s3-tm-migration-unsupported-objects"></a>


| V1 類別 | V2 替代方案 | 遷移狀態 | 
| --- | --- | --- | 
| PauseStatus | 不支援 | 不支援 | 
| UploadContext | 不支援 | 不支援 | 
| ObjectCannedAclProvider | PutObjectRequest.builder().acl() | 不支援 | 
| ObjectMetadataProvider | PutObjectRequest.builder().metadata() | 不支援 | 
| ObjectTaggingProvider | PutObjectRequest.builder().tagging() | 不支援 | 
| PresignedUrlDownload | 不支援 | 不支援 | 

## TransferManagerBuilder 組態遷移
<a name="s3-tm-migration-builder-configuration"></a>

### 組態變更
<a name="migration-transfer-manager-config-changes"></a>

您需要為 v2 Transfer Manager 設定的組態變更取決於您使用的 S3 用戶端。您可以選擇 AWS CRT 型 S3 用戶端或標準 Java 型 S3 非同步用戶端。如需差異的相關資訊，請參閱 [中的 S3 用戶端 AWS SDK for Java 2.x](examples-s3.md#s3-clients)主題。

------
#### [ Use the AWS CRT-based S3 client ]


****  

| 設定 | v1 | v2 - 使用 AWS CRT 型 S3 用戶端的 Transfer Manager | 
| --- | --- | --- | 
|    （取得建置器）  |  <pre>TransferManagerBuilder tmBuilder = <br />   TransferManagerBuilder.standard();</pre>  |  <pre>S3TransferManager.Builder tmBuilder  = <br />  S3TransferManager.builder();</pre>  | 
|    S3 用戶端  |  <pre>tmBuilder.withS3Client(...);<br />tmBuilder.setS3Client(...);</pre>  |  <pre>tmBuilder.s3Client(...);</pre>  | 
|    執行器  |  <pre>tmBuilder.withExecutorFactory(...);<br />tmBuilder.setExecutorFactory(...);</pre>  |  <pre>tmBuilder.executor(...);</pre>  | 
|    關閉執行緒集區  |  <pre>tmBuilder.withShutDownThreadPools(...);<br />tmBuilder.setShutdownThreadPools(...);</pre>  | 不支援。關閉 時，不會關閉提供的執行器 S3TransferManager  | 
|    最小上傳部分大小  |  <pre>tmBuilder.withMinimumUploadPartSize(...);<br />tmBuilder.setMinimumUploadPartSize(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.crtBuilder().<br />      minimumPartSizeInBytes(...).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    分段上傳閾值  |  <pre>tmBuilder.withMultipartUploadThreshold(...);<br />tmBuilder.setMultipartUploadThreshold(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.crtBuilder().<br />      thresholdInBytes(...).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    最小複製部分大小  |  <pre>tmBuilder.withMultipartCopyPartSize(...);<br />tmBuilder.setMultipartCopyPartSize(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.crtBuilder().<br />      minimumPartSizeInBytes(...).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    分段複製閾值  |  <pre>tmBuilder.withMultipartCopyThreshold(...);<br />tmBuilder.setMultipartCopyThreshold(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.crtBuilder().<br />      thresholdInBytes(...).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    停用平行下載  |  <pre>tmBuilder.withDisableParallelDownloads(...);<br />tmBuilder.setDisableParallelDownloads(...);</pre>  | 將停用分段 （預設） 的標準 Java 型 S3 用戶端傳遞給傳輸管理員，以停用平行下載。 <pre>S3AsyncClient s3 =<br />   S3AsyncClient.builder().build();<br /><br />tmBuilder.s3Client(s3);</pre> | 
|    一律計算分段 md5  |  <pre>tmBuilder.withAlwaysCalculateMultipartMd5(...);<br />tmBuilder.setAlwaysCalculateMultipartMd5(...);</pre>  | 不支援。 | 

------
#### [ Use Java-based S3 async client ]


****  

| 設定 | v1 | v2 - 使用 Java 型 S3 非同步用戶端的 Transfer Manager | 
| --- | --- | --- | 
|    （取得建置器）  |  <pre>TransferManagerBuilder tmBuilder = <br />   TransferManagerBuilder.standard();</pre>  |  <pre>S3TransferManager.Builder tmBuilder  = <br />  S3TransferManager.builder();</pre>  | 
|    S3 用戶端  |  <pre>tmBuilder.withS3Client(...);<br />tmBuilder.setS3Client(...);</pre>  |  <pre>tmBuilder.s3Client(...);</pre>  | 
|    執行器  |  <pre>tmBuilder.withExecutorFactory(...);<br />tmBuilder.setExecutorFactory(...);</pre>  |  <pre>tmBuilder.executor(...);</pre>  | 
|    關閉執行緒集區  |  <pre>tmBuilder.withShutDownThreadPools(...);<br />tmBuilder.setShutdownThreadPools(...);</pre>  | 不支援。關閉 時，不會關閉提供的執行器 S3TransferManager  | 
|    最小上傳部分大小  |  <pre>tmBuilder.withMinimumUploadPartSize(...);<br />tmBuilder.setMinimumUploadPartSize(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.builder()<br />    .multipartConfiguration(cfg -><br />        cfg.minimumPartSizeInBytes(...)).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    分段上傳閾值  |  <pre>tmBuilder.withMultipartUploadThreshold(...);<br />tmBuilder.setMultipartUploadThreshold(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.builder()<br />    .multipartConfiguration(cfg -><br />        cfg.thresholdInBytes(...)).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    最小複製部分大小  |  <pre>tmBuilder.withMultipartCopyPartSize(...);<br />tmBuilder.setMultipartCopyPartSize(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.builder()<br />    .multipartConfiguration(cfg -><br />        cfg.minimumPartSizeInBytes(...)).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    分段複製閾值  |  <pre>tmBuilder.withMultipartCopyThreshold(...);<br />tmBuilder.setMultipartCopyThreshold(...);</pre>  |  <pre>S3AsyncClient s3 = S3AsyncClient.builder()<br />    .multipartConfiguration(cfg -><br />        cfg.thresholdInBytes(...)).build();<br /><br />tmBuilder.s3Client(s3);</pre>  | 
|    停用平行下載  |  <pre>tmBuilder.withDisableParallelDownloads(...);<br />tmBuilder.setDisableParallelDownloads(...);</pre>  | 將停用分段 （預設） 的標準 Java 型 S3 用戶端傳遞至傳輸管理員，以停用平行下載。 <pre>S3AsyncClient s3 =<br />   S3AsyncClient.builder().build();<br /><br />tmBuilder.s3Client(s3);</pre> | 
|    一律計算分段 md5  |  <pre>tmBuilder.withAlwaysCalculateMultipartMd5(...);<br />tmBuilder.setAlwaysCalculateMultipartMd5(...);</pre>  | 不支援。 | 

------

## 行為變更
<a name="s3-tm-migration-behavior-changes"></a>

### 非同步操作
<a name="s3-tm-migration-async-operations"></a>

**V1 （封鎖）：**

```
Upload upload = transferManager.upload("amzn-s3-demo-bucket", "key", file);
upload.waitForCompletion(); // Blocks until complete
```

**V2 （非同步）：**

```
FileUpload upload = transferManager.uploadFile(UploadFileRequest.builder()
    .putObjectRequest(PutObjectRequest.builder()
        .bucket("amzn-s3-demo-bucket")
        .key("key")
        .build())
    .source(file)
    .build());

CompletedFileUpload result = upload.completionFuture().join(); // Blocks until complete
// Or handle asynchronously:
upload.completionFuture().thenAccept(result -> {
    System.out.println("Upload completed: " + result.response().eTag());
});
```

### 錯誤處理
<a name="s3-tm-migration-error-handling"></a>

**V1：**如果任何子請求失敗，目錄傳輸會完全失敗。

**V2：**即使某些子請求失敗，目錄傳輸也會成功完成。明確檢查錯誤：

```
DirectoryUpload directoryUpload = transferManager.uploadDirectory(request);
CompletedDirectoryUpload result = directoryUpload.completionFuture().join();

// Check for failed transfers
if (!result.failedTransfers().isEmpty()) {
    System.out.println("Some uploads failed:");
    result.failedTransfers().forEach(failed -> 
        System.out.println("Failed: " + failed.exception().getMessage()));
}
```

### 透過位元組範圍擷取平行下載
<a name="migration-transfer-manager-behavior-fetches"></a>

在 v2 SDK 中啟用自動平行傳輸功能時，S3 Transfer Manager 會使用[位元組範圍擷取](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-guidelines.html#optimizing-performance-guidelines-get-range)來平行擷取物件的特定部分 （分段下載）。使用 v2 下載物件的方式，不取決於最初上傳物件的方式。所有下載都可以受益於高輸送量和並行。

相反地，與 v1 的 Transfer Manager 相比，最初上傳物件的方式並不重要。v1 Transfer Manager 擷取物件組件的方式與上傳組件的方式相同。如果物件最初是以單一物件上傳，v1 Transfer Manager 就無法使用子請求加速下載程序。

# 從第 1 版剖析 Amazon S3 URIs 到第 2 版的變更
<a name="migration-s3-uri-parser"></a>

本主題詳細說明剖析 Amazon S3 URIs 從第 1 版 (v1) 到第 2 版 (v2.) 的變更。

## 高階變更
<a name="migration-3-uri-parser-api-changes"></a>

若要開始剖析 v1 中的 S3 URI，您可以使用建構函數來執行個體化 `AmazonS3URI` 。在 v2 中，您在 執行個體`parseUri()`上呼叫 `S3Utilities`，以傳回 `S3URI`。


****  

| 變更 | v1 |   v2 | 
| --- | --- | --- | 
|    Maven 相依性  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>com.amazonaws</groupId><br />            <artifactId>aws-java-sdk-bom</artifactId><br />            <version>1.12.5871</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency>  <br />        <groupId>com.amazonaws</groupId><br />        <artifactId>s3</artifactId><br />    </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.27.212</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>s3</artifactId><br />    </dependency><br /></dependencies></pre>  | 
| 套件名稱 | com.amazonaws.services.s3 | software.amazon.awssdk.services.s3 | 
| 類別名稱 | [AmazonS3URI](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3URI.html) | [S3URI](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Uri.html) | 

1 [最新版本](https://central.sonatype.com/artifact/com.amazonaws/aws-java-sdk-bom)。 2 [最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。

## API 變更
<a name="migration-3-uri-parser-api-changes"></a>


| Behavior (行為) | v1 |   v2 | 
| --- | --- | --- | 
| 剖析 S3 URI。 |  <pre>URI uri = URI.create( "https://s3.amazonaws.com");<br /><br />AmazonS3Uri s3Uri = <br />    new AmazonS3URI(uri, false);</pre>  |  <pre>S3Client s3Client = S3Client.create();<br />S3Utilities s3Utilities =<br />    s3Client.utilities();<br /><br />S3Uri s3Uri =<br />    s3Utilities.parseUri(uri);</pre>  | 
| 從 S3 URI 擷取儲存貯體名稱。 |  <pre>String bucket = s3Uri.getBucket();</pre>  |  <pre>Optional<String> bucket = s3Uri.bucket();</pre>  | 
| 擷取金鑰。 |  <pre>String key = s3Uri.getKey();</pre>  |  <pre>Optional<String> key = s3Uri.key();</pre>  | 
| 擷取區域。 |  <pre>String region = s3Uri.getRegion();</pre>  |  <pre>Optional<Region> region = s3Uri.region();<br /><br />String region;<br />if (s3Uri.region().isPresent()) {<br />    region = s3Uri.region().get().id();<br />}</pre>  | 
|  擷取 S3 URI 是否為路徑樣式。  |  <pre>boolean isPathStyle = s3Uri.isPathStyle();</pre>  |  <pre>boolean isPathStyle = s3Uri.isPathStyle();</pre>  | 
| 擷取版本 ID。 |  <pre>String versionId = s3Uri.getVersionId();</pre>  |  <pre>Optional<String> versionId = <br />    s3Uri.firstMatchingRawQueryParameter("versionId");</pre>  | 
| 擷取查詢參數。 | N/A |  <pre>Map<String, List<String>> queryParams =<br />    s3Uri.rawQueryParameters();</pre>  | 

### 行為變更
<a name="migration-s3-uri-parser-behavior-changes"></a>

#### URL 編碼
<a name="migration-s3-uri-parser-behavior-changes-URLencoding"></a>

v1 提供傳入旗標的選項，以指定 URI 是否應該以 URL 編碼。預設值為 `true`。

在 v2 中，不支援 URL 編碼。如果您使用具有預留或不安全字元的物件金鑰或查詢參數，則必須進行 URL 編碼。例如，您需要`" "`將空格取代為 `%20`。

# S3 事件通知 API 從第 1 版變更為第 2 版
<a name="migration-s3-event-notification"></a>

本主題詳細說明 S3 事件通知 API 從 版本 1.x (v1) 到 版本 2 .x (v2) 的變更 適用於 Java 的 AWS SDK。

## 高階變更
<a name="migration-s3-event-notification-hl"></a>

### 結構變更
<a name="migration-s3-event-notification-hl-struct"></a>

V1 對`EventNotificationRecord`類型及其屬性使用靜態內部類別，而 v2 對`EventNotificationRecord`類型使用單獨的公有類別。

### 命名慣例變更
<a name="migration-s3-event-notification-hl-naming"></a>

在 v1 中，屬性類別名稱包含尾碼*實體*，而 v2 會省略此尾碼，以進行更簡單的命名：例如 *eventData*，而不是 *eventDataEntity*。

## 相依性、套件和類別名稱的變更
<a name="migration-s3-event-notification-deps"></a>

在 v1 中，S3 事件通知 API 類別會隨著 S3 模組 (artifactId) 暫時匯入`aws-java-sdk-s3`。不過，在 v2 中，您需要在`s3-event-notifications`成品上新增相依性。


****  

| 變更 | v1 |   v2 | 
| --- | --- | --- | 
|    Maven 相依性  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>com.amazonaws</groupId><br />            <artifactId>aws-java-sdk-bom</artifactId><br />            <version>1.X.X</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-java-sdk-s3</artifactId><br />    </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.X.X1</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>s3-event-notifications</artifactId><br />    </dependency><br /></dependencies></pre>  | 
| 套件名稱 | com.amazonaws.services.s3.event | software.amazon.awssdk.eventnotifications.s3.model | 
| 類別名稱 |  [S3EventNotification](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.html) [S3EventNotification.S3EventNotificationRecord](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.S3EventNotificationRecord.html) [ S3EventNotification.GlacierEventDataEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.GlacierEventDataEntity.html) [S3EventNotification.IntelligentTieringEventDataEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.IntelligentTieringEventDataEntity.html) [S3EventNotification.LifecycleEventDataEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.LifecycleEventDataEntity.html) [S3EventNotification.ReplicationEventDataEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.ReplicationEventDataEntity.html) [S3EventNotification.RequestParametersEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.RequestParametersEntity.html) [S3EventNotification.ResponseElementsEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.ResponseElementsEntity.html) [S3EventNotification.RestoreEventDataEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.RestoreEventDataEntity.html) [S3EventNotification.S3BucketEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.S3BucketEntity.html) [ S3EventNotification.S3Entity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.S3Entity.html) [S3EventNotification.S3ObjectEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.S3ObjectEntity.html) [S3EventNotification.TransitionEventDataEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.TransitionEventDataEntity.html) [S3EventNotification.UserIdentityEntity](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/event/S3EventNotification.UserIdentityEntity.html)  |   [S3EventNotification](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/S3EventNotification.html) [S3EventNotificationRecord](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/S3EventNotificationRecord.html) [GlacierEventData](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/GlacierEventData.html) [IntelligentTieringEventData](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/IntelligentTieringEventData.html) [LifecycleEventData](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/LifecycleEventData.html) [ReplicationEventData](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/ReplicationEventData.html) [RequestParameters](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/RequestParameters.html) [ResponseElements](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/ResponseElements.html) [RestoreEventData](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/RestoreEventData.html) [S3 儲存貯體](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/S3Bucket.html) [S3](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/S3.html) [S3Object](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/S3Object.html) [TransitionEventData](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/TransitionEventData.html) [UserIdentity](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/UserIdentity.html)  | 

1 [最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。

## API 變更
<a name="migration-s3-event-notification-API-changes"></a>

### JSON 至 `S3EventNotification`和反向
<a name="migration-s3-event-notification-API-changes-conv"></a>


| 使用案例 | v1 |   v2 | 
| --- | --- | --- | 
| S3EventNotification 從 JSON 字串建立 |  <pre>S3EventNotification notification = <br />        S3EventNotification.parseJson(message.body());</pre>  |  <pre>S3EventNotification notification = <br />        S3EventNotification.fromJson(message.body());</pre>  | 
| S3EventNotification 轉換為 JSON 字串 |  <pre>String json = notification.toJson();</pre>  |  <pre>String json = notification.toJson();</pre>  | 

### 的存取屬性 `S3EventNotification`
<a name="migration-s3-event-notification-API-changes-attr"></a>


| 使用案例 | v1 |   v2 | 
| --- | --- | --- | 
| 從通知擷取記錄 |  <pre>List<S3EventNotification.S3EventNotificationRecord> records = <br />        notifcation.getRecords();</pre>  |  <pre>List<S3EventNotificationRecord> records = <br />        notification.getRecords();</pre>  | 
| 從記錄清單中擷取記錄 |  <pre>S3EventNotification.S3EventNotificationRecord record = <br />        records.stream().findAny().get();</pre>  |  <pre>S3EventNotificationRecord record = <br />        records.stream().findAny().get();</pre>  | 
| 擷取 Glacier 事件資料 |  <pre>S3EventNotification.GlacierEventDataEntity glacierEventData =<br />        record.getGlacierEventData();</pre>  |  <pre>GlacierEventData glacierEventData = <br />        record.getGlacierEventData();</pre>  | 
| 從 Glacier 事件擷取還原事件資料 |  <pre>S3EventNotification.RestoreEventDataEntity restoreEventData = <br />        glacierEventData.getRestoreEventDataEntity();</pre>  |  <pre>RestoreEventData restoreEventData = <br />        glacierEventData.getRestoreEventData();</pre>  | 
| 擷取請求參數 |  <pre>S3EventNotification.RequestParametersEntity requestParameters = <br />        record.getRequestParameters();</pre>  |  <pre>RequestParameters requestParameters = <br />        record.getRequestParameters();</pre>  | 
| 擷取智慧型分層事件資料 |  <pre>S3EventNotification.IntelligentTieringEventDataEntity tieringEventData = <br />        record.getIntelligentTieringEventData();</pre>  |  <pre>IntelligentTieringEventData intelligentTieringEventData = <br />        record.getIntelligentTieringEventData();</pre>  | 
| 擷取生命週期事件資料 |  <pre>S3EventNotification.LifecycleEventDataEntity lifecycleEventData = <br />        record.getLifecycleEventData();</pre>  |  <pre>LifecycleEventData lifecycleEventData = <br />        record.getLifecycleEventData();</pre>  | 
| 擷取事件名稱做為列舉 |  <pre>S3Event eventNameAsEnum = record.getEventNameAsEnum();</pre>  |  <pre>//getEventNameAsEnum does not exist; use 'getEventName()'<br />String eventName = record.getEventName();</pre>  | 
| 擷取複寫事件資料 |  <pre>S3EventNotification.ReplicationEventDataEntity replicationEntity = <br />        record.getReplicationEventDataEntity();</pre>  |  <pre>ReplicationEventData replicationEventData = <br />        record.getReplicationEventData();</pre>  | 
| 擷取 S3 儲存貯體和物件資訊 |  <pre>S3EventNotification.S3Entity s3 = record.getS3();</pre>  |  <pre>S3 s3 = record.getS3();</pre>  | 
| 擷取使用者身分資訊 |  <pre>S3EventNotification.UserIdentityEntity userIdentity = <br />        record.getUserIdentity();</pre>  |  <pre>UserIdentity userIdentity = <br />        record.getUserIdentity();</pre>  | 
| 擷取回應元素 |  <pre>S3EventNotification.ResponseElementsEntity responseElements = <br />        record.getResponseElements();</pre>  |  <pre>ResponseElements responseElements = <br />        record.getResponseElements();</pre>  | 

## 遷移程式`aws-lambda-java-events`庫版本
<a name="migration-s3-events-notification-lambda-lib"></a>

如果您使用 [aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events) 在 Lambda 函數中使用 S3 通知事件，我們建議您升級至最新的 3.x.x 版本。最近的版本會從 S3 事件通知 API 消除 適用於 Java 的 AWS SDK 1.x 上的所有相依性。

如需處理`aws-lambda-java-events`程式庫與適用於 Java 的 SDK 2.x 之間 S3 事件通知差異的詳細資訊，請參閱 [使用 Java 程式庫處理 Lambda 中的 S3 事件： AWS SDK for Java 2.x 和 `aws-lambda-java-events`](examples-s3-event-notifications.md#s3-event-notif-processing-options)。

# 設定檔檔案變更
<a name="migration-profile-file"></a>

會剖析 AWS SDK for Java 2.x `~/.aws/config`和 中的設定檔定義`~/.aws/credentials`，以更緊密地模擬 AWS CLI 剖析檔案的方式。

適用於 Java 的 SDK 2.x：
+ 依序檢查 `$HOME`、 `$USERPROFILE`（僅限 Windows)、、 `$HOMEDRIVE``$HOMEPATH`（僅限 Windows)，然後檢查系統屬性，以解決路徑開頭的檔案`user.home`系統預設路徑分隔符號 `~/`或`~`後面的 。
+ 尋找`AWS_SHARED_CREDENTIALS_FILE`環境變數，而非 `AWS_CREDENTIAL_PROFILES_FILE`。
+ 在設定檔名稱`profile`開頭沒有單字的情況下，在組態檔案中無提示地捨棄設定檔定義。
+ 無提示地捨棄不由英數字元、底線或破折號字元組成的設定檔定義 （在組態檔案移除前綴`profile`字詞之後）。
+ 合併相同檔案中重複的設定檔定義設定。
+ 合併組態和登入資料檔案中重複的設定檔定義設定。
+ 如果 `[profile foo]`和 在相同的 檔案中同時`[foo]`找到 ，則不會合併設定。
+ `[profile foo]` 如果在組態檔案中同時找到 `[profile foo]`和 `[foo]` ，則使用 中的設定。
+ 使用相同檔案和設定檔中上次複製設定的值。
+ 識別 `;`和 `#`以定義註解。
+ 識別設定檔定義`#`中的 `;`和 以定義註解，即使字元與結尾括號相鄰。
+ 只有在值前面加上空格時，才能辨識`;`並`#`定義註解。
+ 如果值前面沒有空格，則識別值中的 `#` `;`和 以及所有下列內容。
+ 將角色型登入資料視為最高優先順序登入資料。如果使用者指定 `role_arn` 屬性，則 2.x SDK 一律使用角色型登入資料。
+ 將工作階段型登入資料視為second-highest-priority登入資料。如果未使用角色型登入資料，且使用者指定 `aws_access_key_id`和 `aws_session_token` 屬性，則 2.x SDK 一律會使用工作階段型登入資料。
+ 如果未使用角色型和工作階段型登入資料，且使用者指定 `aws_access_key_id` 屬性，則使用基本登入資料。

# 環境變數和系統屬性變更
<a name="migration-env-and-system-props"></a>


| 1.x 環境變數 | 1.x 系統屬性 | 2.x 環境變數 | 2.x 系統屬性 | 
| --- | --- | --- | --- | 
| AWS\$1ACCESS\$1KEY\$1IDAWS\$1ACCESS\$1KEY | aws.accessKeyId | AWS\$1ACCESS\$1KEY\$1ID | aws.accessKeyId | 
| AWS\$1SECRET\$1KEYAWS\$1SECRET\$1ACCESS\$1KEY | aws.secretKey | AWS\$1SECRET\$1ACCESS\$1KEY | aws.secretAccessKey | 
| AWS\$1SESSION\$1TOKEN | aws.sessionToken | AWS\$1SESSION\$1TOKEN | aws.sessionToken | 
| AWS\$1REGION | aws.region | AWS\$1REGION | aws.region | 
| AWS\$1CONFIG\$1FILE |   | AWS\$1CONFIG\$1FILE | aws.configFile | 
| AWS\$1CREDENTIAL\$1PROFILES\$1FILE |   | AWS\$1SHARED\$1CREDENTIALS\$1FILE | aws.sharedCredentialsFile | 
| AWS\$1PROFILE | aws.profile | AWS\$1PROFILE | aws.profile | 
| AWS\$1EC2\$1METADATA\$1DISABLED | com.amazonaws.sdk.disableEc2Metadata | AWS\$1EC2\$1METADATA\$1DISABLED | aws.disableEc2Metadata | 
|   | com.amazonaws.sdk.ec2MetadataServiceEndpointOverride | AWS\$1EC2\$1METADATA\$1SERVICE\$1ENDPOINT | aws.ec2MetadataServiceEndpoint | 
| AWS\$1CONTAINER\$1CREDENTIALS\$1RELATIVE\$1URI |   | AWS\$1CONTAINER\$1CREDENTIALS\$1RELATIVE\$1URI | aws.containerCredentialsPath | 
| AWS\$1CONTAINER\$1CREDENTIALS\$1FULL\$1URI |   | AWS\$1CONTAINER\$1CREDENTIALS\$1FULL\$1URI | aws.containerCredentialsFullUri | 
| AWS\$1CONTAINER\$1AUTHORIZATION\$1TOKEN |   | AWS\$1CONTAINER\$1AUTHORIZATION\$1TOKEN | aws.containerAuthorizationToken | 
| AWS\$1CBOR\$1DISABLED | com.amazonaws.sdk.disableCbor | CBOR\$1ENABLED | aws.cborEnabled | 
| AWS\$1ION\$1BINARY\$1DISABLE | com.amazonaws.sdk.disableIonBinary | BINARY\$1ION\$1ENABLED | aws.binaryIonEnabled | 
| AWS\$1EXECUTION\$1ENV |   | AWS\$1EXECUTION\$1ENV | aws.executionEnvironment | 
|   | com.amazonaws.sdk.disableCertChecking | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
|   | com.amazonaws.sdk.enableDefaultMetrics | [不支援](https://github.com/aws/aws-sdk-java-v2/issues/23) | [不支援](https://github.com/aws/aws-sdk-java-v2/issues/23) | 
|   | com.amazonaws.sdk.enableThrottledRetry | [不支援](https://github.com/aws/aws-sdk-java-v2/issues/645) | [不支援](https://github.com/aws/aws-sdk-java-v2/issues/645) | 
|   | com.amazonaws.regions.RegionUtils.fileOverride | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
|   | com.amazonaws.regions.RegionUtils.disableRemote | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
|   | com.amazonaws.services.s3.disableImplicitGlobalClients | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 
|   | com.amazonaws.sdk.enableInRegionOptimizedMode | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 不支援 ([請求功能](https://github.com/aws/aws-sdk-java-v2/issues/new)) | 

# 等待程式從第 1 版變更為第 2 版
<a name="migration-waiters"></a>

本主題詳細說明等待程式功能從第 1 版 (v1) 到第 2 版 (v2) 的變更。

下表特別示範 DynamoDB 等待程式的差異。其他服務的等待程式遵循相同的模式。

## 高階變更
<a name="migration-waiters-api-changes"></a>

等待程式類別與 服務位於相同的 Maven 成品。


| 變更 | v1 | v2 | 
| --- | --- | --- | 
|    Maven 相依性  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>com.amazonaws</groupId><br />            <artifactId>aws-java-sdk-bom</artifactId><br />            <version>1.12.6801</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>dynamodb</artifactId><br />    </dependency><br /></dependencies><br /></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.27.102</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>dynamodb</artifactId><br />    </dependency><br /></dependencies></pre>  | 
| 套件名稱 | com.amazonaws.services.dynamodbv2.waiters | software.amazon.awssdk.services.dynamodb.waiters | 
| 類別名稱 |  `[AmazonDynamoDBWaiters](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/waiters/AmazonDynamoDBWaiters.html)`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/migration-waiters.html)  | 

1 [最新版本](https://central.sonatype.com/artifact/com.amazonaws/aws-java-sdk-bom)。 2 [最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。

## API 變更
<a name="migration-cf-presign-behavior-changes"></a>


| 變更 | v1 | v2 | 
| --- | --- | --- | 
| 建立等待程式 |  <pre>AmazonDynamoDB client = AmazonDynamoDBClientBuilder <br />                            .standard().build();<br />AmazonDynamoDBWaiters waiter = client.waiters();</pre>  | 同步：<pre>DynamoDbClient client = DynamoDbClient.create();<br />DynamoDbWaiter waiter = client.waiter();</pre>非同步：<pre>DynamoDbAsyncClient asyncClient = <br />        DynamoDbAsyncClient.create();<br />DynamoDbAsyncWaiter waiter = asyncClient.waiter();</pre> | 
| 等到資料表存在 | 同步：<pre>waiter.tableExists()<br />    .run(new WaiterParameters<>(<br />        new DescribeTableRequest(tableName)));</pre>非同步：<pre>waiter.tableExists()<br />    .runAsync(new WaiterParameters()<br />      .withRequest(new DescribeTableRequest(tableName)),<br />          new WaiterHandler() {<br />              @Override<br />              public void onWaitSuccess(<br />                  AmazonWebServiceRequest amazonWebServiceRequest) {<br />                    System.out.println("Table creation succeeded");<br />              }<br /><br />              @Override<br />              public void onWaitFailure(Exception e) {<br />                  e.printStackTrace();<br />              }<br />          }).get();</pre> |  同步： <pre>WaiterResponse<DescribeTableResponse> waiterResponse =<br />    waiter.waitUntilTableExists(<br />        r -> r.tableName("myTable"));<br />waiterResponse.matched().response()<br />       .ifPresent(System.out::println);</pre> 非同步： <pre>waiter.waitUntilTableExists(r -> r.tableName(tableName))<br />           .whenComplete((r, t) -> {<br />               if (t != null) {<br />                   t.printStackTrace();<br />               } else {<br />                   System.out.println(<br />                        "Table creation succeeded");<br />               }<br />           }).join();</pre>  | 

## 組態變更
<a name="migration-waiters-config"></a>


| 變更 | v1 | v2 | 
| --- | --- | --- | 
| 輪詢策略 （最大嘗試次數和固定延遲） |  <pre>MaxAttemptsRetryStrategy maxAttemptsRetryStrategy = <br />        new MaxAttemptsRetryStrategy(10);<br /><br />FixedDelayStrategy fixedDelayStrategy = <br />        new FixedDelayStrategy(3);<br /><br />PollingStrategy pollingStrategy = <br />        new PollingStrategy(maxAttemptsRetryStrategy, <br />                fixedDelayStrategy);<br /><br />waiter.tableExists().run(<br />        new WaiterParameters<>(<br />            new DescribeTableRequest(tableName)), <br />                pollingStrategy);</pre>  |  <pre><br />FixedDelayBackoffStrategy fixedDelayBackoffStrategy = <br />        FixedDelayBackoffStrategy<br />            .create(Duration.ofSeconds(3));<br /><br />waiter.waitUntilTableExists(r -> r.tableName(tableName),<br />        c -> c.maxAttempts(10)<br />                .backoffStrategy(fixedDelayBackoffStrategy));</pre>  | 

# EC2 中繼資料公用程式從第 1 版變更為第 2 版
<a name="migration-imds"></a>

本主題詳細說明適用於 Java 的 SDK Amazon Elastic Compute Cloud (EC2) 中繼資料公用程式從第 1 版 (v1) 到第 2 版 (v2) 的變更。

## 高階變更
<a name="migration-imds-high-level-changes"></a>


****  

| 變更 | v1 |   v2 | 
| --- | --- | --- | 
|    Maven 相依性  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>com.amazonaws</groupId><br />            <artifactId>aws-java-sdk-bom</artifactId><br />            <version>1.12.5871</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-java-sdk-core</artifactId><br />    </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.27.212</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>imds</artifactId><br />    </dependency><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>apache-client3</artifactId><br />    </dependency><br /></dependencies></pre>  | 
| 套件名稱 |  com.amazonaws.util  |  software.amazon.awssdk.imds  | 
| 執行個體化方法 |  使用靜態公用程式方法；無執行個體化： <pre>String localHostName = <br />           EC2MetadataUtils.getLocalHostName();</pre>  |  使用靜態原廠方法： <pre>Ec2MetadataClient client = Ec2MetadataClient.create();</pre> 或使用建置器方法： <pre>Ec2MetadataClient client = Ec2MetadataClient.builder()<br />    .endpointMode(EndpointMode.IPV6)<br />    .build();</pre>  | 
| 用戶端類型 | 僅同步公用程式方法： EC2MetadataUtils |  同步： `Ec2MetadataClient` 非同步： `Ec2MetadataAsyncClient`  | 

1 [最新版本](https://central.sonatype.com/artifact/com.amazonaws/aws-java-sdk-bom)。 2 [最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。

3通知 v2 `apache-client`模組的宣告。EC2 中繼資料公用程式的 V2 需要實作同步中繼資料用戶端的 `SdkHttpClient` 界面，或非同步中繼資料用戶端的 `SdkAsyncHttpClient`界面。 EC2 [在 中設定 HTTP 用戶端 AWS SDK for Java 2.x](http-configuration.md) 區段顯示您可以使用的 HTTP 用戶端清單。

### 請求中繼資料
<a name="migration-imds-fetching-changes"></a>

在 v1 中，您可以使用不接受參數的靜態方法來請求 EC2 資源的中繼資料。相反地，您需要在 v2 中指定 EC2 資源的路徑做為參數。下表顯示不同的方法。


****  

| v1 |   v2 | 
| --- | --- | 
|  <pre>String userMetaData = EC2MetadataUtils.getUserData();</pre>  |  <pre>Ec2MetadataClient client = Ec2MetadataClient.create();<br />Ec2MetadataResponse response = <br />                client.get("/latest/user-data");<br />String userMetaData = <br />                response.asString();</pre>  | 

請參閱[執行個體中繼資料類別](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/instancedata-data-categories.html)，以尋找請求中繼資料所需的路徑。

**注意**  
當您在 v2 中使用執行個體中繼資料用戶端時，您應該目標是針對擷取中繼資料的所有請求使用相同的用戶端。

 

## 行為變更
<a name="migration-imds-behavior-changes"></a>

### JSON 資料
<a name="migration-imds-behavior-json"></a>

在 EC2 上，本機執行的執行個體中繼資料服務 (IMDS) 會以 JSON 格式字串傳回一些中繼資料。其中一個範例是[執行個體身分文件](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/instance-identity-documents.html)的動態中繼資料。

v1 API 包含每個執行個體身分中繼資料的個別方法，而 v2 API 會直接傳回 JSON 字串。若要使用 JSON 字串，您可以使用[文件 API ](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/document/package-summary.html) 來剖析回應並導覽 JSON 結構。

下表比較如何在 v1 和 v2 中擷取執行個體身分文件的中繼資料。


****  

| 使用案例 | v1 |   v2 | 
| --- | --- | --- | 
| 擷取區域 |  <pre>InstanceInfo instanceInfo = <br />        EC2MetadataUtils.getInstanceInfo();<br />String region = instanceInfo.getRegion();</pre>  |  <pre>Ec2MetadataResponse response = <br />    client.get("/latest/dynamic/instance-identity/document");<br />Document instanceInfo = response.asDocument();<br />String region = instanceInfo.asMap().get("region").asString();</pre>  | 
| 擷取執行個體 ID |  <pre>InstanceInfo instanceInfo = <br />        EC2MetadataUtils.getInstanceInfo();<br />String instanceId = instanceInfo.instanceId;</pre>  |  <pre>Ec2MetadataResponse response = <br />    client.get("/latest/dynamic/instance-identity/document");<br />Document instanceInfo = response.asDocument();<br />String instanceId = instanceInfo.asMap().get("instanceId").asString();</pre>  | 
| 擷取執行個體類型 |  <pre>InstanceInfo instanceInfo = <br />        EC2MetadataUtils.getInstanceInfo();<br />String instanceType = instanceInfo.instanceType();</pre>  |  <pre>Ec2MetadataResponse response = <br />    client.get("/latest/dynamic/instance-identity/document");<br />Document instanceInfo = response.asDocument();<br />String instanceType = instanceInfo.asMap().get("instanceType").asString();</pre>  | 

### 端點解析差異
<a name="migration-imds-behavior-endpoint-res"></a>

下表顯示 SDK 檢查的位置，以將端點解析為 IMDS。這些位置會以遞減優先順序列出。


****  

| v1 |   v2 | 
| --- | --- | 
| 系統屬性： com.amazonaws.sdk.ec2MetadataServiceEndpointOverride | 用戶端建置器組態方法： endpoint(...) | 
| 環境變數： AWS\$1EC2\$1METADATA\$1SERVICE\$1ENDPOINT | 系統屬性： aws.ec2MetadataServiceEndpoint | 
| 預設值：http://169.254.169.254 | Config 檔案：\$1.aws/config使用 ec2\$1metadata\$1service\$1endpoint設定 | 
|  | 已解析與 相關聯的值 endpoint-mode  | 
|  | 預設值：http://169.254.169.254 | 

### v2 中的端點解析
<a name="migration-imds-behavior-endpoint-res2"></a>

當您使用建置器明確設定端點時，該端點值會優先於所有其他設定。執行下列程式碼時，`aws.ec2MetadataServiceEndpoint`系統屬性和組態檔案`ec2_metadata_service_endpoint`設定會在存在時予以忽略。

```
Ec2MetadataClient client = Ec2MetadataClient
  .builder()
  .endpoint(URI.create("endpoint.to.use"))
  .build();
```

#### 端點模式
<a name="migration-imds-behavior-endpoint-mode"></a>

透過 v2，您可以指定端點模式，將中繼資料用戶端設定為使用 IPv4 或 IPv6 的預設端點值。端點模式不適用於 v1。用於 IPv4 的預設值為 `http://[fd00:ec2::254]` IPv6 的 `http://169.254.169.254`和 。 IPv6

下表顯示您可以依遞減優先順序設定端點模式的不同方式。


****  

|  |  | 可能的值 | 
| --- | --- | --- | 
| 用戶端建置器組態方法： endpointMode(...) |  <pre>Ec2MetadataClient client = Ec2MetadataClient<br />  .builder()<br />  .endpointMode(EndpointMode.IPV4)<br />  .build();</pre>  | EndpointMode.IPV4, EndpointMode.IPV6 | 
| 系統屬性 | aws.ec2MetadataServiceEndpointMode | IPv4、 IPv6（大小寫無關緊要） | 
| 組態檔案： \$1.aws/config | ec2\$1metadata\$1service\$1endpoint 設定 | IPv4、 IPv6（大小寫無關緊要） | 
| 先前未指定 | 使用 IPv4  |  | 

#### 開發套件如何在 v2 `endpoint-mode`中解析 `endpoint`或
<a name="migration-imds-behavior-endpoint-res2-which"></a>

1. SDK 會使用您在用戶端建置器程式碼中設定的值，並忽略任何外部設定。由於軟體開發套件會在用戶端建置器上`endpointMode`同時呼叫 `endpoint`和 時擲回例外狀況，因此軟體開發套件會使用您使用任何方法的端點值。

1. 如果您未在程式碼中設定值，軟體開發套件會先尋找外部組態，然後再尋找組態檔案中的設定。

   1. 開發套件會先檢查端點值。如果找到值，則會使用該值。

   1. 如果軟體開發套件仍然找不到值，軟體開發套件會尋找端點模式設定。

1. 最後，如果軟體開發套件找不到外部設定，而且您尚未在程式碼中設定中繼資料用戶端，則軟體開發套件會使用 的 IPv4 值`http://169.254.169.254`。

### IMDSV2
<a name="migration-imds-behavior-imdsv2"></a>

Amazon EC2 定義兩種存取執行個體中繼資料的方法：
+ 執行個體中繼資料服務第 1 版 (IMDSv1) – 請求/回應方法
+ 執行個體中繼資料服務第 2 版 (IMDSv2) – 工作階段導向方法

下表比較 Java SDKs如何使用 IMDS。


****  

| v1 |   v2 | 
| --- | --- | 
| 根據預設會使用 IMDSv2  | 一律使用 IMDSv2 | 
| 嘗試為每個請求擷取工作階段字符，如果無法擷取工作階段字符，則會回到 IMDSv1  | 將工作階段字符保留在針對多個請求重複使用的內部快取中 | 

適用於 Java 的 SDK 2.x 僅支援 IMDSv2，不會回復為 IMDSv1。

## 組態差異
<a name="migration-imds-config-diffs"></a>

下表列出不同的組態選項。


****  

| Configuration | v1 |   v2 | 
| --- | --- | --- | 
| 重試 | 組態無法使用 | 可透過建置器方法設定 retryPolicy(...) | 
| HTTP | 可透過環境AWS\$1METADATA\$1SERVICE\$1TIMEOUT變數設定連線逾時。預設值為 1 秒。 | 將 HTTP 用戶端傳遞至建置器方法 即可使用組態httpClient(...)。HTTP 用戶端的預設連線逾時為 2 秒。 | 

### 範例 v2 HTTP 組態
<a name="migration-imds-http-conf-v2-ex"></a>

下列範例示範如何設定中繼資料用戶端。此範例會設定連線逾時，並使用 Apache HTTP 用戶端。

```
SdkHttpClient httpClient = ApacheHttpClient.builder()
    .connectionTimeout(Duration.ofSeconds(1))
    .build();

Ec2MetadataClient imdsClient = Ec2MetadataClient.builder()
    .httpClient(httpClient)
    .build();
```

# 從第 1 版到第 2 版的 Amazon CloudFront 預先簽章變更
<a name="migration-cloudfront-presigning"></a>

本主題詳細說明 Amazon CloudFront 從第 1 版 (v1) 到第 2 版 (v2) 的變更。

## 高階變更
<a name="migration-cloudfront-presigning-api-changes"></a>


****  

| 變更 | v1 |   v2 | 
| --- | --- | --- | 
|    Maven 相依性  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>com.amazonaws</groupId><br />            <artifactId>aws-java-sdk-bom</artifactId><br />            <version>1.12.5871</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency>  <br />        <groupId>com.amazonaws</groupId><br />        <artifactId>cloudfront</artifactId><br />    </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.27.212</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>cloudfront</artifactId><br />    </dependency><br /></dependencies></pre>  | 
| 套件名稱 | com.amazonaws.services.cloudfront | software.amazon.awssdk.services.cloudfront | 
| 類別名稱 |  [CloudFrontUrlSigner](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/cloudfront/CloudFrontUrlSigner.html) [CloudFrontCookieSigner](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/cloudfront/CloudFrontCookieSigner.html)  |  [CloudFrontUtilities](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudfront/CloudFrontUtilities.html) [SignedUrl](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudfront/url/SignedUrl.html) [CannedSignerRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudfront/model/CannedSignerRequest.html) [CustomSignerRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudfront/model/CustomSignerRequest.html)  | 

1 [最新版本](https://central.sonatype.com/artifact/com.amazonaws/aws-java-sdk-bom)。 2 [最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。

## API 變更
<a name="migration-cf-presign-behavior-changes"></a>


| Behavior (行為) | v1 |   v2 | 
| --- | --- | --- | 
| 建置標準請求 | 引數會直接傳遞至 API。 |  <pre>CannedSignerRequest cannedRequest =<br />      CannedSignerRequest.builder()<br />                         .resourceUrl(resourceUrl)<br />                         .privateKey(privateKey)<br />                         .keyPairId(keyPairId)<br />                         .expirationDate(expirationDate)<br />                         .build();</pre>  | 
| 建置自訂請求 | 引數會直接傳遞至 API。 |  <pre>CustomSignerRequest customRequest =<br />      CustomSignerRequest.builder()<br />                         .resourceUrl(resourceUrl)<br />                         .resourceUrlPattern(resourceUrlPattern)<br />                         .privateKey(keyFile)<br />                         .keyPairId(keyPairId)<br />                         .expirationDate(expirationDate)<br />                         .activeDate(activeDate)<br />                         .ipRange(ipRange)<br />                         .build();</pre>  | 
| 產生已簽署的 URL （標準） |  <pre>String signedUrl =<br />  CloudFrontUrlSigner.getSignedURLWithCannedPolicy(<br />    resourceUrl, keyPairId, privateKey, expirationDate);</pre>  |  <pre>CloudFrontUtilities cloudFrontUtilities =<br />    CloudFrontUtilities.create();<br /><br />SignedUrl signedUrl =        <br />    cloudFrontUtilities.getSignedUrlWithCannedPolicy(cannedRequest);<br /><br />String url = signedUrl.url();<br /></pre>  | 
| 產生已簽章的 Cookie （自訂） |  <pre>CookiesForCustomPolicy cookies =<br />    CloudFrontCookieSigner.getCookiesForCustomPolicy(<br />        resourceUrl, privateKey, keyPairId, expirationDate, <br />        activeDate, ipRange);<br /></pre>  |  <pre>CloudFrontUtilities cloudFrontUtilities =<br />    CloudFrontUtilities.create();<br /><br />CookiesForCustomPolicy cookies =<br />     cloudFrontUtilities.getCookiesForCustomPolicy(customRequest);<br /></pre>  | 

### v2 中的重構 Cookie 標頭
<a name="migration-cf-presign-behavior-headers"></a>

在 Java v1 中，Java 開發套件會以 形式提供 Cookie 標頭`Map.Entry<String, String>`。

```
Map.Entry<String, String> signatureMap = cookies.getSignature();
String signatureKey = signatureMap.getKey(); // "CloudFront-Signature"
String signatureValue = signatureMap.getValue(); // "[SIGNATURE_VALUE]"
```

Java v2 SDK 以單一 形式交付整個標頭`String`。

```
String signatureHeaderValue = cookies.signatureHeaderValue(); // "CloudFront-Signature=[SIGNATURE_VALUE]"
```

# IAM 政策建置器 API 從第 1 版變更為第 2 版
<a name="migration-iam-policy-builder"></a>

本主題詳細說明 IAM 政策建置器 API 從第 1 版 (v1) 到第 2 版 (v2) 的變更。

## 高階變更
<a name="migration-iam-policy-builder-high-level"></a>


****  

| 變更 | v1 |   v2 | 
| --- | --- | --- | 
|    Maven 相依性  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>com.amazonaws</groupId><br />            <artifactId>aws-java-sdk-bom</artifactId><br />            <version>1.12.5871</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-java-sdk-core</artifactId><br />    </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.27.212</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>iam-policy-builder</artifactId><br />    </dependency><br /></dependencies></pre>  | 
| 套件名稱 | com.amazonaws.auth.policy | software.amazon.awssdk.policybuilder.iam | 
| 類別名稱 |  [政策](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/Policy.html) [Statement](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/Statement.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/migration-iam-policy-builder.html)  |  [IamPolicy](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamPolicy.html) [IamStatement](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamStatement.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/migration-iam-policy-builder.html)  | 

1 [最新版本](https://central.sonatype.com/artifact/com.amazonaws/aws-java-sdk-bom)。 2 [最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。

## API 變更
<a name="migration-iam-policy-builder-api"></a>


****  

| 設定 | v1 |   v2 | 
| --- | --- | --- | 
|  執行個體化政策 |  <pre>Policy policy = new Policy();</pre>  |  <pre>IamPolicy.Builder policyBuilder = IamPolicy.builder();<br />...<br />IamPolicy policy = policyBuilder.build();</pre>  | 
|    設定 ID  |  <pre>policy.withtId(...);<br />policy.setId(...);</pre>  |  <pre>policyBuilder.id(...);</pre>  | 
|    設定版本  | 不適用 - 使用預設版本的 2012-10-17 |  <pre>policyBuilder.version(...);</pre>  | 
|    建立陳述式  |  <pre>Statement statement = <br />    new Statement(Effect.Allow)<br />            .withActions(...)<br />            .withConditions(...)<br />            .withId(...)<br />            .withPrincipals(...)<br />            .withResources(...);</pre>  |  <pre>IamStatement statement = <br />    IamStatement.builder()<br />            .effect(IamEffect.ALLOW)<br />            .actions(...)<br />            .notActions(...)<br />            .conditions(...)<br />            .sid(...)<br />            .principals(...)<br />            .notPrincipals(...)<br />            .resources(...)<br />            .notResources(...)<br />            .build()</pre>  | 
|    設定陳述式  |  <pre>policy.withStatements(statement);<br />policy.setStatements(statement);</pre>  |  <pre>policyBuilder.addStatement(statement);</pre>  | 

## 建置陳述式的差異
<a name="migration-iam-policy-builder-statement"></a>

### 動作
<a name="migration-iam-policy-builder-statement-actions"></a>

#### v1
<a name="migration-iam-policy-builder-statement-actions.v1"></a>

v1 SDK 具有代表政策陳述式中`[https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_action.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_action.html)`元素的服務動作[`enum`類型](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/Action.html)。以下是`enum`一些範例。
+ `[IdentityManagementActions](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/actions/IdentityManagementActions.html)`
+ `[DynamoDBv2Actions](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/actions/DynamoDBv2Actions.html)`
+ `[SQSActions](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/actions/SQSActions.html)`

下列範例顯示 的`SendMessage`常數`SQSActions`。

```
Action action = SQSActions.SendMessage;
```

您無法在 v1 中指定陳述式的`[https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notaction.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notaction.html)`元素。

####   v2
<a name="migration-iam-policy-builder-statement-actions.v2"></a>

在 v2 中，[IamAction](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamAction.html) 界面代表所有動作。若要指定[服務特定的動作](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_action.html)元素，請將字串傳遞至 `create`方法，如下列程式碼所示。

```
IamAction action = IamAction.create("sqs:SendMessage");
```

您可以`[https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notaction.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notaction.html)`為 v2 的陳述式指定 ，如下列程式碼所示。

```
IamAction action = IamAction.create("sqs:SendMessage");
IamStatement.builder().addNotAction(action);
```

### 條件
<a name="migration-iam-policy-builder-statement-conditions"></a>

#### v1
<a name="migration-iam-policy-builder-statement-conditions-v1"></a>

為了表示陳述式條件，v1 SDK 使用 的子類別[https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/Condition.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/Condition.html)。
+  [ArnCondition](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/conditions/ArnCondition.html) 
+  [BooleanCondition](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/conditions/BooleanCondition.html)
+  [DateCondition](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/conditions/DateCondition.html)
+ [IpAddressCondition](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/conditions/IpAddressCondition.html)
+ [NumericCondition](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/conditions/NumericCondition.html)
+ [ StringCondition ](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/conditions/StringCondition.html)

每個`Condition`子類別都會定義比較`enum`類型，以協助定義條件。例如，以下顯示*不同於*條件的[字串比較](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String)。

```
Condition condition = new StringCondition(StringComparisonType.StringNotLike, "key", "value");
```

####   v2
<a name="migration-iam-policy-builder-statement-conditions-v2"></a>

在 v2 中，您可以使用 為政策陳述式建置條件，`[IamCondition](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamCondition.html)`並提供 `[IamConditionOperator](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamConditionOperator.html)`，其中包含`enums`所有類型的 。

```
IamCondition condition = IamCondition.create(IamConditionOperator.STRING_NOT_LIKE, "key", "value");
```

### Resources
<a name="migration-iam-policy-builder-statement-resources"></a>

#### v1
<a name="migration-iam-policy-builder-statement-resources-v1"></a>

政策陳述式的 `[https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_resource.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_resource.html)` 元素由 SDK 的 `[Resource](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/Resource.html)`類別表示。您可以在建構函數中提供 ARN 做為字串。下列子類別提供方便的建構函式。
+ [S3BucketResource](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/resources/S3BucketResource.html)
+ [S3ObjectResource](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/resources/S3ObjectResource.html)
+ [SQSQueueResource](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/resources/SQSQueueResource.html)

在 v1 中，您可以`[Resource](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/Resource.html)`呼叫 `withIsNotType`方法來指定 的 `[https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notresource.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notresource.html)` 元素，如下列陳述式所示。

```
Resource resource = new Resource("arn:aws:s3:::amzn-s3-demo-bucket").withIsNotType(true);
```

####   v2
<a name="migration-iam-policy-builder-statement-resources-v2"></a>

在 v2 中，您將 ARN 傳遞至 `IamResource.create`方法來建立 `[https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_resource.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_resource.html)`元素。

```
IamResource resource = IamResource.create("arn:aws:s3:::amzn-s3-demo-bucket");
```

`[IamResource](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamResource.html)` 可以設定為*[https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notresource.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notresource.html)*元素，如下列程式碼片段所示。

```
IamResource resource = IamResource.create("arn:aws:s3:::amzn-s3-demo-bucket");
IamStatement.builder().addNotResource(resource);
```

`IamResource.ALL` 代表所有資源。

### 主體
<a name="migration-iam-policy-builder-statement-principal"></a>

#### v1
<a name="migration-iam-policy-builder-statement-principal-v1"></a>

v1 SDK 提供下列`[Principal](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/policy/Principal.html)`類別，代表包含所有成員的主體類型：
+ `AllUsers`
+ `AllServices`
+ `AllWebProviders`
+ `All`

您無法將`[https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notprincipal.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notprincipal.html)`元素新增至陳述式。

####   v2
<a name="migration-iam-policy-builder-statement-principal-v2"></a>

在 v2 中， `IamPrincipal.ALL`代表所有主體：

若要代表其他類型委託人中的所有成員，請在建立 時使用 `[IamPrincipalType](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamPrincipalType.html)`類別`IamPrincipal`。
+ `IamPrincipal.create(IamPrincipalType.AWS,"*")` 適用於所有使用者。
+ `IamPrincipal.create(IamPrincipalType.SERVICE,"*")` 適用於所有 服務。
+ `IamPrincipal.create(IamPrincipalType.FEDERATED,"*")` 適用於所有 Web 供應商。
+ `IamPrincipal.create(IamPrincipalType.CANONICAL_USER,"*")` 適用於所有正式使用者。

當您建立政策陳述式時，您可以使用 `addNotPrincipal`方法代表`[https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notprincipal.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notprincipal.html)`元素，如下列陳述式所示。

```
IamPrincipal principal = IamPrincipal.create(IamPrincipalType.AWS, "arn:aws:iam::444455556666:root");
IamStatement.builder().addNotPrincipal(principal);
```

# 使用 DynamoDB 從 第 1 版變更為 第 2 版 適用於 Java 的 AWS SDK
<a name="migration-ddb-mapper"></a>



**Topics**
+ [

# 第 1 版與第 2 版之間的 DynamoDB 映射 API 差異 適用於 Java 的 AWS SDK
](ddb-mapping.md)
+ [

# 記錄 第 1 版和第 2 版之間的 API 差異 適用於 Java 的 AWS SDK
](dynamodb-mapping-document-api.md)
+ [

# 加密程式庫遷移
](ddb-encryption-lib-migrate.md)

# 第 1 版與第 2 版之間的 DynamoDB 映射 API 差異 適用於 Java 的 AWS SDK
<a name="ddb-mapping"></a>

DynamoDB 映射 APIs 第 1 版和第 2 版之間發生重大變更 適用於 Java 的 AWS SDK。在第 1 版中，您可以使用 `DynamoDBMapper` 來使用 Java POJOs。在第 2 版中，您可以使用 `DynamoDbEnhancedClient` 搭配更新的方法名稱、增強型結構描述定義選項，以及改善的類型安全性。

主要差異包括：
+ 新的方法名稱 （例如 `getItem` 而非 `load`)
+ 明確資料表結構描述建立
+ 同步和非同步操作的內建支援
+ 如何處理空白字串和組態的變更

本節涵蓋映射 API 變更、註釋差異、組態更新和遷移指引，以協助您從 v1 轉換`DynamoDBMapper`到 v2`DynamoDbEnhancedClient`。

**Contents**
+ [

# 從適用於 Java 的 SDK 第 1 版到第 2 版映射程式庫的高階變更
](dynamodb-mapping-high-level.md)
  + [

## 匯入相依性差異
](dynamodb-mapping-high-level.md#dynamodb-mapping-deps)
+ [

# 適用於 Java 的 SDK 第 1 版和第 2 版之間的 DynamoDB 映射 APIs 變更
](dynamodb-mapping-api-changes.md)
  + [

## 建立用戶端
](dynamodb-mapping-api-changes.md#dynamodb-mapping-api-changes-client)
  + [

## 建立對 DynamoDB 資料表/索引的映射
](dynamodb-mapping-api-changes.md#dynamodb-mapping-api-changes-mapping)
  + [

## 資料表操作
](dynamodb-mapping-api-changes.md#dynamodb-mapping-api-changes-tobleops)
  + [

## 映射類別和屬性
](dynamodb-mapping-api-changes.md#dynamodb-mapping-schemas)
    + [

### Bean 註釋
](dynamodb-mapping-api-changes.md#dynamodb-mapping-schemas-annos)
    + [

### V2 其他註釋
](dynamodb-mapping-api-changes.md#dynamodb-mapping-schemas-annos-v2-addnl)
  + [

## Configuration
](dynamodb-mapping-api-changes.md#dynamodb-mapping-configuration)
    + [

### 每個操作組態
](dynamodb-mapping-api-changes.md#dynamodb-mapping-configuration-per-op)
  + [

## 有條件
](dynamodb-mapping-api-changes.md#dynamodb-mapping-conditionals)
  + [

## 類型轉換
](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv)
    + [

### 預設轉換器
](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv-defaults)
    + [

### 設定屬性的自訂轉換器
](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv-anno)
    + [

### 新增類型轉換器工廠或供應商
](dynamodb-mapping-api-changes.md#dynamodb-mapping-type-conv-factory)
+ [

# 適用於 Java 的 SDK 第 1 版和第 2 版之間的字串處理差異
](dynamodb-migration-string-handling.md)
+ [

# 適用於 Java 的 SDK 第 1 版和第 2 版之間的樂觀鎖定差異
](dynamodb-migrate-optimstic-locking.md)
+ [

# 適用於 Java 的 SDK 第 1 版和第 2 版之間的流暢設定器差異
](dynamodb-migrate-fluent-setters.md)

# 從適用於 Java 的 SDK 第 1 版到第 2 版映射程式庫的高階變更
<a name="dynamodb-mapping-high-level"></a>

每個程式庫中的映射用戶端名稱在 V1 和 V2 中不同：
+ V1 - DynamoDBMapper
+ V2 - DynamoDB 增強型用戶端

您以大致相同的方式與兩個程式庫互動：您執行個體化映射器/用戶端，然後將 Java POJO 提供給讀取和寫入這些項目至 DynamoDB 資料表APIs。這兩個程式庫也提供 POJO 類別的註釋，以指示用戶端如何處理 POJO。

移至 V2 時的顯著差異包括：
+ V2 和 V1 對低階 DynamoDB 操作使用不同的方法名稱。例如：    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/dynamodb-mapping-high-level.html)
+ V2 提供多種方法來定義資料表結構描述，並將 POJOs對應至資料表。您可以選擇使用註釋，或使用建置器從程式碼產生的結構描述。V2 還提供結構描述的可變和不可變版本。
+ 使用 V2 時，您會特別將資料表結構描述建立為第一個步驟之一，而在 V1 中，則會視需要從註釋的類別推斷資料表結構描述。
+ V2 在增強型[用戶端 API 中包含文件 ](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html) API 用戶端，而 V1 使用[單獨的 API](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/DynamoDB.html)。
+ 所有 APIs V2 中提供同步和非同步版本。

如需 V2 增強型用戶端的詳細資訊，請參閱本指南中的 [DynamoDB 映射一節](dynamodb-enhanced-client.md)。

## 匯入相依性差異
<a name="dynamodb-mapping-deps"></a>


| V1 | V2 | 
| --- | --- | 
|  <pre><dependencyManagement><br />  <dependencies><br />    <dependency><br />      <groupId>com.amazonaws</groupId><br />      <artifactId>aws-java-sdk-bom</artifactId><br />      <version>1.X.X</version><br />      <type>pom</type><br />      <scope>import</scope><br />    </dependency><br />  </dependencies><br /></dependencyManagement> <br /><br /><dependencies><br />  <dependency><br />    <groupId>com.amazonaws</groupId><br />    <artifactId>aws-java-sdk-dynamodb</artifactId><br />  </dependency><br /></dependencies></pre>  |  <pre><dependencyManagement><br />  <dependencies><br />    <dependency><br />      <groupId>software.amazon.awssdk</groupId><br />      <artifactId>bom</artifactId><br />      <version>2.X.X*</version><br />      <type>pom</type><br />      <scope>import</scope><br />    </dependency><br />  </dependencies><br /></dependencyManagement> <br /><br /><dependencies><br />  <dependency><br />    <groupId>software.amazon.awssdk</groupId><br />    <artifactId>dynamodb-enhanced</artifactId><br />  </dependency><br /></dependencies></pre>  | 

\$1 [最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。

在 V1 中，單一相依性同時包含低階 DynamoDB API 和映射/文件 API，而在 V2 中，您可以使用`dynamodb-enhanced`成品相依性來存取映射/文件 API。`dynamodb-enhanced` 模組包含低階`dynamodb`模組的暫時性相依性。

# 適用於 Java 的 SDK 第 1 版和第 2 版之間的 DynamoDB 映射 APIs 變更
<a name="dynamodb-mapping-api-changes"></a>

## 建立用戶端
<a name="dynamodb-mapping-api-changes-client"></a>


****  

| 使用案例 | V1 | V2 | 
| --- | --- | --- | 
|   正常執行個體化  |  <pre>AmazonDynamoDB standardClient = AmazonDynamoDBClientBuilder.standard()<br />    .withCredentials(credentialsProvider)<br />    .withRegion(Regions.US_EAST_1)<br />    .build();<br />DynamoDBMapper mapper = new DynamoDBMapper(standardClient);</pre>  |  <pre>DynamoDbClient standardClient = DynamoDbClient.builder()<br />    .credentialsProvider(ProfileCredentialsProvider.create())<br />    .region(Region.US_EAST_1)<br />    .build();<br />DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()<br />    .dynamoDbClient(standardClient)<br />    .build();</pre>  | 
|   最小執行個體化  |  <pre>AmazonDynamoDB standardClient = AmazonDynamoDBClientBuilder.standard();<br />DynamoDBMapper mapper = new DynamoDBMapper(standardClient);</pre>  |  <pre>DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.create();</pre>  | 
|   使用屬性轉換器\$1  |  <pre>DynamoDBMapper mapper = new DynamoDBMapper(standardClient, <br />                        attributeTransformerInstance);</pre>  |  <pre>DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()<br />    .dynamoDbClient(standardClient)<br />    .extensions(extensionAInstance, extensionBInstance)<br />    .build();</pre>  | 

\$1V2 中的延伸大致對應至 V1 中的屬性轉換器。[使用擴充功能自訂 DynamoDB 增強型用戶端操作](ddb-en-client-extensions.md) 本節包含 V2 中延伸模組的詳細資訊。

## 建立對 DynamoDB 資料表/索引的映射
<a name="dynamodb-mapping-api-changes-mapping"></a>

在 V1 中，您可以透過 Bean 註釋指定 DynamoDB 資料表名稱。在 V2 中，原廠方法 `table()`會產生`DynamoDbTable`代表遠端 DynamoDB 資料表的 執行個體。`table()` 方法的第一個參數是 DynamoDB 資料表名稱。


****  

| 使用案例 | V1 | V2 | 
| --- | --- | --- | 
|   將 Java POJO 類別映射至 DynamoDB 資料表  |  <pre>@DynamoDBTable(tableName ="Customer")<br />public class Customer {<br />  ...<br />}</pre>  |  <pre>DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer",<br />    TableSchema.fromBean(Customer.class));</pre>  | 
|   映射至 DynamoDB 次要索引  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html) DynamoDB 開發人員指南中討論[ V1 `query`方法](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html#DynamoDBMapper.Methods.query)的 區段會顯示完整的範例。  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html) 本指南中的 [使用次要索引](ddb-en-client-use-secindex.md)區段提供更多資訊。  | 

## 資料表操作
<a name="dynamodb-mapping-api-changes-tobleops"></a>

本節說明適用於大多數標準使用案例的 V1 和 V2 之間的操作 APIs。

在 V2 中，所有涉及單一資料表的操作都會在`DynamoDbTable`執行個體上呼叫，而不是在增強型用戶端上呼叫。增強型用戶端包含可將多個資料表設為目標的方法。

在下列名為*資料表操作*的資料表中，POJO 執行個體稱為 `item`或特定類型，例如 `customer1`。對於名為 的執行個體的 V2 範例， `table`是先前呼叫 `enhancedClient.table()`傳回執行個體參考的結果`DynamoDbTable`。

請注意，即使未顯示，大多數 V2 操作也可以使用流暢的消費者模式來呼叫。例如 

```
Customer customer = table.getItem(r → r.key(key));
  or
Customer customer = table.getItem(r → r.key(k -> k.partitionValue("id").sortValue("email")))
```

對於 V1 操作，*資料表操作* （下方） 包含一些常用表單，而不是所有超載表單。例如， `load()`方法具有下列過載：

```
mapper.load(Customer.class, hashKey)
mapper.load(Customer.class, hashKey, rangeKey)
mapper.load(Customer.class, hashKey, config)
mapper.load(Customer.class, hashKey, rangeKey, config)
mapper.load(item)
mapper.load(item, config)
```

*資料表操作* （下方） 顯示常用的表單：

```
mapper.load(item)
mapper.load(item, config)
```


**資料表操作**  

| 使用案例 | V1 | V2 | 
| --- | --- | --- | 
|  將 Java POJO 寫入 DynamoDB 資料表 **DynamoDB 操作：**`PutItem`、 `UpdateItem`  |  <pre>mapper.save(item)<br />mapper.save(item, config)<br />mapper.save(item, saveExpression, config)</pre> 在 V1 中， `DynamoDBMapperConfig.SaveBehavior`和 註釋會決定要呼叫哪個低階 DynamoDB 方法。一般而言， `UpdateItem` 會在使用 `SaveBehavior.CLOBBER`和 時呼叫 `SaveBehavior.PUT`。自動產生的金鑰是特殊的使用案例，偶爾同時使用 `UpdateItem` `PutItem`和 。  |  <pre>table.putItem(putItemRequest)<br />table.putItem(item)<br />table.putItemWithResponse(item) //Returns metadata.<br /><br />updateItem(updateItemRequest)<br />table.updateItem(item)<br />table.updateItemWithResponse(item) //Returns metadata.</pre>  | 
|  從 DynamoDB 資料表將項目讀取至 Java POJO **DynamoDB 操作：** `GetItem`  |  <pre>mapper.load(item)<br />mapper.load(item, config)</pre>  |  <pre>table.getItem(getItemRequest)<br />table.getItem(item)<br />table.getItem(key)<br />table.getItemWithResponse(key) //Returns POJO with metadata.</pre>  | 
|  從 DynamoDB 資料表刪除項目 **DynamoDB 操作：** `DeleteItem`  |  <pre>mapper.delete(item, deleteExpression, config)</pre>  |  <pre>table.deleteItem(deleteItemRequest)<br />table.deleteItem(item)<br />table.deleteItem(key)</pre>  | 
|  查詢 DynamoDB 資料表或次要索引並傳回分頁清單 **DynamoDB 操作：** `Query`  |  <pre>mapper.query(Customer.class, queryExpression)<br />mapper.query(Customer.class, queryExpression, <br />                             mapperConfig)</pre>  |  <pre>table.query(queryRequest)<br />table.query(queryConditional)</pre> 將傳回的 `PageIterable.stream()`（延遲載入） 用於同步回應和非`PagePublisher.subscribe()`同步回應  | 
|  查詢 DynamoDB 資料表或次要索引並傳回清單 **DynamoDB 操作：** `Query`  |  <pre>mapper.queryPage(Customer.class, queryExpression)<br />mapper.queryPage(Customer.class, queryExpression, <br />                                 mapperConfig)</pre>  |  <pre>table.query(queryRequest)<br />table.query(queryConditional)</pre> 將傳回的 `PageIterable.items()`（延遲載入） 用於同步回應和非`PagePublisher.items.subscribe()`同步回應  | 
|  掃描 DynamoDB 資料表或次要索引並傳回分頁清單 **DynamoDB 操作：** `Scan`  |  <pre>mapper.scan(Customer.class, scanExpression)<br />mapper.scan(Customer.class, scanExpression, <br />                            mapperConfig)</pre>  |  <pre>table.scan()<br />table.scan(scanRequest)</pre> 將傳回的 `PageIterable.stream()`（延遲載入） 用於同步回應和非`PagePublisher.subscribe()`同步回應  | 
|  掃描 DynamoDB 資料表或次要索引並傳回清單 **DynamoDB 操作：** `Scan`  |  <pre>mapper.scanPage(Customer.class, scanExpression)<br />mapper.scanPage(Customer.class, scanExpression, <br />                                mapperConfig)</pre>  |  <pre>table.scan()<br />table.scan(scanRequest)</pre> 將傳回的 `PageIterable.items()`（延遲載入） 用於同步回應和非`PagePublisher.items.subscribe()`同步回應  | 
|  從批次中的多個資料表讀取多個項目 **DynamoDB 操作：** `BatchGetItem`  |  <pre>mapper.batchLoad(Arrays.asList(customer1, <br />                               customer2, <br />                               book1))<br />mapper.batchLoad(itemsToGet) <br />           // itemsToGet: Map<Class<?>, List<KeyPair>></pre>  |  <pre>enhancedClient.batchGetItem(batchGetItemRequest)<br /><br />enhancedClient.batchGetItem(r -> r.readBatches(<br />    ReadBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addGetItem(i -> i.key(k -> k.partitionValue(0)))<br />             .build(),<br />    ReadBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addGetItem(i -> i.key(k -> k.partitionValue(0)))<br />             .build()))<br /><br />// Iterate over pages with lazy loading or over all items <br />   from the same table.</pre>  | 
|  將多個項目寫入批次中的多個資料表 **DynamoDB 操作：** `BatchWriteItem`  |  <pre>mapper.batchSave(Arrays.asList(customer1, <br />                               customer2, <br />                               book1)) </pre>  |  <pre>enhancedClient.batchWriteItem(batchWriteItemRequest)<br /><br />enhancedClient.batchWriteItem(r -> r.writeBatches(<br />    WriteBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addPutItem(item1)<br />             .build(),<br />    WriteBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addPutItem(item2)<br />             .build()))</pre>  | 
|  從批次中的多個資料表刪除多個項目 **DynamoDB 操作：** `BatchWriteItem`  |  <pre>mapper.batchDelete(Arrays.asList(customer1, <br />                                 customer2, <br />                                 book1)) </pre>  |  <pre>enhancedClient.batchWriteItem(r -> r.writeBatches(<br />    WriteBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addDeleteItem(item1key)<br />             .build(),<br />    WriteBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addDeleteItem(item2key)<br />             .build()))</pre>  | 
|  寫入/刪除批次中的多個項目 **DynamoDB 操作：** `BatchWriteItem`  |  <pre>mapper.batchWrite(Arrays.asList(customer1, book1), <br />                  Arrays.asList(customer2)) </pre>  |  <pre>enhancedClient.batchWriteItem(r -> r.writeBatches(<br />    WriteBatch.builder(Record1.class)<br />             .mappedTableResource(mappedTable1)<br />             .addPutItem(item1)<br />             .build(),<br />    WriteBatch.builder(Record2.class)<br />             .mappedTableResource(mappedTable2)<br />             .addDeleteItem(item2key)<br />             .build()))</pre>  | 
|  執行交易寫入 **DynamoDB 操作：** `TransactWriteItems`  |  <pre>mapper.transactionWrite(transactionWriteRequest)</pre>  |  <pre>enhancedClient.transactWriteItems(transasctWriteItemsRequest)</pre>  | 
|  執行交易讀取 **DynamoDB 操作：** `TransactGetItems`  |  <pre>mapper.transactionLoad(transactionLoadRequest)</pre>  |  <pre>enhancedClient.transactGetItems(transactGetItemsRequest) </pre>  | 
|  取得查詢相符項目的計數 **DynamoDB 操作：**`Query`使用 `Select.COUNT`  |  <pre>mapper.count(Customer.class, queryExpression)</pre>  |  <pre>// Get the count from query results.<br />PageIterable<Customer> pageIterable =<br />    customerTable.query(QueryEnhancedRequest.builder()<br />        .queryConditional(queryConditional)<br />        .select(Select.COUNT)<br />        .build());<br />Iterator<Page<Customer>> iterator = pageIterable.iterator();<br />Page<Customer> page = iterator.next();<br />int count = page.count();<br /><br />// For a more concise approach, you can chain the method calls:<br />int count = customerTable.query(QueryEnhancedRequest.builder()<br />                .queryConditional(queryConditional)<br />                .select(Select.COUNT)<br />                .build())<br />            .iterator().next().count();</pre>  | 
|  取得掃描相符項目的計數 **DynamoDB 操作：**`Scan`使用 `Select.COUNT`  |  <pre>mapper.count(Customer.class, scanExpression)</pre>  |  <pre>// Get the count from scan results.<br />PageIterable<Customer> pageIterable =<br />    customerTable.scan(ScanEnhancedRequest.builder()<br />        .filterExpression(filterExpression)<br />        .select(Select.COUNT)<br />        .build());<br />Iterator<Page<Customer>> iterator = pageIterable.iterator();<br />Page<Customer> page = iterator.next();<br />int count = page.count();<br /><br />// For a more concise approach, you can chain the method calls:<br />int count = customerTable.scan(ScanEnhancedRequest.builder()<br />                .filterExpression(filterExpression)<br />                .select(Select.COUNT)<br />                .build())<br />            .iterator().next().count();</pre>  | 
|  在對應至 POJO 類別的 DynamoDB 中建立資料表 **DynamoDB 操作：** `CreateTable`  |  <pre>mapper.generateCreateTableRequest(Customer.class)</pre> 先前的陳述式會產生低階建立資料表請求；使用者必須在 DynamoDB 用戶端`createTable`上呼叫 。  |  <pre>table.createTable(createTableRequest)<br /><br />table.createTable(r -> r.provisionedThroughput(defaultThroughput())<br />    .globalSecondaryIndices(<br />        EnhancedGlobalSecondaryIndex.builder()<br />            .indexName("gsi_1")<br />            .projection(p -> p.projectionType(ProjectionType.ALL))<br />            .provisionedThroughput(defaultThroughput())<br />            .build()));</pre>  | 
|  在 DynamoDB 中執行平行掃描 **DynamoDB 操作：**`Scan`使用 `Segment`和 `TotalSegments` 參數  |  <pre>mapper.parallelScan(Customer.class, <br />                    scanExpression, <br />                    numTotalSegments)</pre>  |  使用者需要處理`scan`每個區段的工作者執行緒和呼叫： <pre>table.scan(r -> r.segment(0).totalSegments(5))</pre>  | 
|  將 Amazon S3 與 DynamoDB 整合，以存放智慧型 S3 連結  |  <pre>mapper.createS3Link(bucket, key)<br />mapper.getS3ClientCache()</pre>  |  不支援，因為它會耦合 Amazon S3 和 DynamoDB。  | 

## 映射類別和屬性
<a name="dynamodb-mapping-schemas"></a>

在 V1 和 V2 中，您可以使用 Bean 樣式註釋將類別映射至資料表。V2 也提供[其他方法來定義特定使用案例的結構描述](ddb-en-client-adv-features.md#ddb-en-client-adv-features-schm-overview)，例如使用不可變類別。

### Bean 註釋
<a name="dynamodb-mapping-schemas-annos"></a>

下表顯示 V1 和 V2 中使用的特定使用案例的同等 Bean 註釋。`Customer` 類別案例用於說明參數。

在 V2 中，註釋以及類別和列舉都遵循駱駝案例慣例，並使用「DynamoDb」，而不是「DynamoDB」。


| 使用案例 | V1 | V2 | 
| --- | --- | --- | 
| 將類別映射至資料表 |  <pre>@DynamoDBTable (tableName ="CustomerTable")</pre>  | <pre>@DynamoDbBean<br />@DynamoDbBean(converterProviders = {...})</pre>呼叫 DynamoDbEnhancedClient\$1table()方法時會定義資料表名稱。 | 
| 將類別成員指定為資料表屬性  |  <pre>@DynamoDBAttribute(attributeName = "customerName")</pre>  |  <pre>@DynamoDbAttribute("customerName") </pre>  | 
| 指定類別成員是雜湊/分割區索引鍵 |  <pre>@DynamoDBHashKey </pre>  |  <pre>@DynamoDbPartitionKey</pre>  | 
| 指定類別成員是範圍/排序索引鍵 |  <pre>@DynamoDBRangeKey </pre>  |  <pre>@DynamoDbSortKey </pre>  | 
| 指定類別成員是次要索引雜湊/分割區索引鍵 |  <pre>@DynamoDBIndexHashKey </pre>  |  <pre>@DynamoDbSecondaryPartitionKey </pre>  | 
| 指定類別成員是次要索引範圍/排序索引鍵 |  <pre>@DynamoDBIndexRangeKey </pre>  |  <pre>@DynamoDbSecondarySortKey </pre>  | 
| 映射至資料表時忽略此類別成員 |  <pre>@DynamoDBIgnore </pre>  |  <pre>@DynamoDbIgnore</pre>  | 
| 將類別成員指定為自動產生的 UUID 金鑰屬性 |  <pre>@DynamoDBAutoGeneratedKey</pre>  |  <pre>@DynamoDbAutoGeneratedUuid </pre> 根據預設，不會載入提供此項目的延伸模組；您必須將延伸模組新增至用戶端建置器。  | 
| 將類別成員指定為自動產生的時間戳記屬性 |  <pre>@DynamoDBAutoGeneratedTimestamp</pre>  |  <pre>@DynamoDbAutoGeneratedTimestampAttribute</pre> 根據預設，不會載入提供此項目的延伸模組；您必須將延伸模組新增至用戶端建置器。  | 
| 將類別成員指定為自動遞增版本屬性 |  <pre>@DynamoDBVersionAttribute</pre>  |  <pre>@DynamoDbVersionAttribute</pre> 自動載入提供此功能的延伸模組。  | 
| 將類別成員指定為需要自訂轉換 |  <pre>@DynamoDBTypeConverted</pre>  |  <pre>@DynamoDbConvertedBy</pre>  | 
| 指定要儲存為不同屬性類型的類別成員 |  <pre>@DynamoDBTyped(<DynamoDBAttributeType>)</pre>  |  使用 `AttributeConverter`實作。V2 為常見 Java 類型提供許多內建轉換器。您也可以實作自己的自訂 `AttributeConverter`或 `AttributeConverterProvider`。請參閱本指南[控制屬性轉換](ddb-en-client-adv-features-conversion.md)中的 。  | 
| 指定可序列化為 DynamoDB 文件 (JSON 樣式文件） 或子文件的類別  |  <pre>@DynamoDBDocument</pre>  | 使用增強型文件 API。請參閱下列資源：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html) | 

### V2 其他註釋
<a name="dynamodb-mapping-schemas-annos-v2-addnl"></a>


| 使用案例 | V1 | V2 | 
| --- | --- | --- | 
| 如果 Java 值為 null，則指定類別成員不要儲存為 NULL 屬性 | N/A |  <pre>@DynamoDbIgnoreNulls</pre>  | 
| 如果所有屬性都是 null，請將類別成員指定為空白物件 | N/A |  <pre>@DynamoDbPreserveEmptyObject</pre>  | 
| 為類別成員指定特殊更新動作 | N/A |  <pre>@DynamoDbUpdateBehavior</pre>  | 
| 指定不可變類別 | N/A |  <pre>@DynamoDbImmutable</pre>  | 
| 將類別成員指定為自動遞增的計數器屬性 | N/A |  <pre>@DynamoDbAtomicCounter</pre> 自動載入提供此功能的延伸模組。  | 

## Configuration
<a name="dynamodb-mapping-configuration"></a>

在 V1 中，您通常會使用 執行個體來控制特定行為`DynamoDBMapperConfig`。您可以在建立映射器或提出請求時提供組態物件。在 V2 中，組態專屬於 操作的請求物件。


| 使用案例 | V1 | V1 中的預設值 | V2 | 
| --- | --- | --- | --- | 
|  |  <pre>DynamoDBMapperConfig.builder()</pre>  |  |  | 
| 批次載入/寫入重試策略 |  <pre>  .withBatchLoadRetryStrategy(loadRetryStrategy)</pre> <pre>  .withBatchWriteRetryStrategy(writeRetryStrategy)</pre>  | 重試失敗的項目 | 在基礎 上設定重試策略DynamoDBClient。請參閱本指南[在 中設定重試行為 AWS SDK for Java 2.x](retry-strategy.md)中的 。 | 
| 一致的讀取 |  <pre>  .withConsistentReads(CONSISTENT)</pre>  | EVENTUAL | 根據預設，讀取操作的一致性讀取為 false。在請求物件.consistentRead(true)上使用 覆寫 。 | 
| 具有 marshallers/unmarshallers 集的轉換結構描述 |  <pre>  .withConversionSchema(conversionSchema)</pre> 靜態實作提供與舊版的回溯相容性。  | V2\$1COMPATIBLE | 不適用。這是舊版功能，指 DynamoDB (V1) 儲存資料類型的最早版本，而且此行為不會保留在增強型用戶端中。DynamoDB V1 中的行為範例是將布林值儲存為數字而非布林值。 | 
| 資料表名稱 |  <pre>  .withObjectTableNameResolver()<br />  .withTableNameOverride() <br />  .withTableNameResolver()</pre> 靜態實作提供與舊版的回溯相容性  | 使用 類別的註釋或猜測 |  呼叫 `DynamoDbEnhancedClient#table()`方法時會定義資料表名稱。  | 
| 分頁載入策略 |  <pre>  .withPaginationLoadingStrategy(strategy)</pre>  選項為：LAZY\$1`EAGER_LOADING`、 `LOADING`或 `ITERATION_ONLY`  | LAZY\$1LOADING |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/dynamodb-mapping-api-changes.html)  | 
| 請求指標集合 |  <pre>  .withRequestMetricCollector(collector)</pre>  | null | 在建置標準 DynamoDB 用戶端metricPublisher()ClientOverrideConfiguration時使用 。 | 
| 儲存行為 |  <pre>  .withSaveBehavior(SaveBehavior.CLOBBER) </pre> 選項為 `UPDATE`、`CLOBBER`、`APPEND_SET`、 `PUT`或 `UPDATE_SKIP_NULL_ATTRIBUTES`。  | UPDATE |  在 V2 中，您可以明確呼叫 `putItem()`或 `updateItem()` 。 `CLOBBER or PUT`：v 2 中的對應動作正在呼叫 `putItem()`。沒有特定的`CLOBBER`組態。 `UPDATE`：對應至 `updateItem()` `UPDATE_SKIP_NULL_ATTRIBUTES`：對應至 `updateItem()`。使用請求設定`ignoreNulls`和註釋/標籤 控制更新行為`DynamoDbUpdateBehavior`。 `APPEND_SET`：不支援  | 
| 類型轉換器工廠 |  <pre>  .withTypeConverterFactory(typeConverterFactory) </pre>  | 標準類型轉換器 |  使用 在 Bean 上設定 <pre>@DynamoDbBean(converterProviders = {ConverterProvider.class, <br />        DefaultAttributeConverterProvider.class})</pre>  | 

### 每個操作組態
<a name="dynamodb-mapping-configuration-per-op"></a>

在 V1 中，某些操作，例如 `query()`，可透過提交至操作的「運算式」物件進行高度設定。例如：

```
DynamoDBQueryExpression<Customer> emailBwQueryExpr = new DynamoDBQueryExpression<Customer>()
    .withRangeKeyCondition("Email",
        new Condition()
            .withComparisonOperator(ComparisonOperator.BEGINS_WITH)
            .withAttributeValueList(
                new AttributeValue().withS("my")));

mapper.query(Customer.class, emailBwQueryExpr);
```

在 V2 中，您可以使用建置器在請求物件上設定參數，而不是使用組態物件。例如：

```
QueryEnhancedRequest emailBw = QueryEnhancedRequest.builder()
    .queryConditional(QueryConditional
        .sortBeginsWith(kb -> kb
            .sortValue("my"))).build();

customerTable.query(emailBw);
```

## 有條件
<a name="dynamodb-mapping-conditionals"></a>

在 V2 中，條件式和篩選表達式會使用 物件來表示，該`Expression`物件會封裝條件以及名稱和篩選條件的映射。


| 使用案例 | 作業 | V1 | V2 | 
| --- | --- | --- | --- | 
| 預期的屬性條件 | save()， delete()， query()， scan() |  <pre>new DynamoDBSaveExpression()<br />  .withExpected(Collections.singletonMap(<br />      "otherAttribute", new ExpectedAttributeValue(false)))<br />  .withConditionalOperator(ConditionalOperator.AND);</pre>  | 已棄用；請ConditionExpression改用 。 | 
| 條件表達式 | delete() |  <pre>deleteExpression.setConditionExpression("zipcode = :zipcode")<br />deleteExpression.setExpressionAttributeValues(...)<br /></pre>  |  <pre>Expression conditionExpression =<br />    Expression.builder()<br />        .expression("#key = :value OR #key1 = :value1")<br />        .putExpressionName("#key", "attribute")<br />        .putExpressionName("#key1", "attribute3")<br />        .putExpressionValue(":value", AttributeValues.stringValue("wrong"))<br />        .putExpressionValue(":value1", AttributeValues.stringValue("three"))<br />        .build();<br /><br />DeleteItemEnhancedRequest request = DeleteItemEnhancedRequest.builder()<br />         .conditionExpression(conditionExpression).build();</pre>  | 
| 篩選條件表達式 | query()， scan() |  <pre>scanExpression<br />  .withFilterExpression("#statename = :state")<br />  .withExpressionAttributeValues(attributeValueMapBuilder.build())<br />  .withExpressionAttributeNames(attributeNameMapBuilder.build())<br /></pre>  |  <pre>Map<String, AttributeValue> values = singletonMap(":key", stringValue("value"));<br />Expression filterExpression =<br />    Expression.builder()<br />        .expression("name = :key")<br />        .expressionValues(values)<br />        .build();<br />QueryEnhancedRequest request = QueryEnhancedRequest.builder()<br />    .filterExpression(filterExpression).build();<br /></pre>  | 
| 查詢的條件表達式 | query() |  <pre>queryExpression.withKeyConditionExpression()</pre>  |  <pre>QueryConditional keyEqual = QueryConditional.keyEqualTo(b -> b<br />                .partitionValue("movie01"));<br /><br />QueryEnhancedRequest tableQuery = QueryEnhancedRequest.builder()<br />                .queryConditional(keyEqual)<br />                .build();</pre>  | 

## 類型轉換
<a name="dynamodb-mapping-type-conv"></a>

### 預設轉換器
<a name="dynamodb-mapping-type-conv-defaults"></a>

在 V2 中， SDK 為所有常見類型提供一組預設轉換器。您可以在整體供應商層級以及單一屬性變更類型轉換器。您可以在 [AttributeConverter](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverter.html) API 參考中找到可用轉換器的清單。

### 設定屬性的自訂轉換器
<a name="dynamodb-mapping-type-conv-anno"></a>

在 V1 中，您可以使用 註釋 getter 方法`@DynamoDBTypeConverted`，以指定在 Java 屬性類型和 DynamoDB 屬性類型之間轉換的類別。例如，可在 Java `Currency`類型和 DynamoDB 字串之間`CurrencyFormatConverter`轉換的 可套用，如下列程式碼片段所示。

```
@DynamoDBTypeConverted(converter = CurrencyFormatConverter.class)
public Currency getCurrency() { return currency; }
```

上一個程式碼片段的 V2 對等項目如下所示。

```
@DynamoDbConvertedBy(CurrencyFormatConverter.class)
public Currency getCurrency() { return currency; }
```

**注意**  
在 V1 中，您可以將註釋套用至屬性本身 、類型或使用者定義的註釋，V2 僅支援將註釋套用至 getter。

### 新增類型轉換器工廠或供應商
<a name="dynamodb-mapping-type-conv-factory"></a>

在 V1 中，您可以提供自己的一組類型轉換器，或透過將類型轉換器工廠新增至組態來覆寫您關心的類型。類型轉換器工廠擴展 `DynamoDBTypeConverterFactory`，覆寫是透過取得預設設定的參考並將其擴展來完成。下列程式碼片段示範如何執行此操作。

```
DynamoDBTypeConverterFactory typeConverterFactory =
    DynamoDBTypeConverterFactory.standard().override()
        .with(String.class, CustomBoolean.class, new DynamoDBTypeConverter<String, CustomBoolean>() {
            @Override
            public String convert(CustomBoolean bool) {
                return String.valueOf(bool.getValue());
            }
            @Override
            public CustomBoolean unconvert(String string) {
                return new CustomBoolean(Boolean.valueOf(string));
            }}).build();
DynamoDBMapperConfig config =
    DynamoDBMapperConfig.builder()
        .withTypeConverterFactory(typeConverterFactory)
        .build();
DynamoDBMapper mapperWithTypeConverterFactory = new DynamoDBMapper(dynamo, config);
```

V2 透過`@DynamoDbBean`註釋提供類似的功能。您可以提供單一`AttributeConverterProvider`或一組已排序的 `AttributeConverterProvider`。請注意，如果您提供自己的屬性轉換器提供者鏈，您將覆寫預設轉換器提供者，且必須將其包含在鏈中，才能使用其屬性轉換器。

```
@DynamoDbBean(converterProviders = {
   ConverterProvider1.class, 
   ConverterProvider2.class,
   DefaultAttributeConverterProvider.class})
public class Customer {
  ...
}
```

本指南中[屬性轉換](ddb-en-client-adv-features-conversion.md#ddb-en-client-adv-features-conversion-example)的 區段包含 V2 的完整範例。

# 適用於 Java 的 SDK 第 1 版和第 2 版之間的字串處理差異
<a name="dynamodb-migration-string-handling"></a>

將資料傳送至 DynamoDB 時，V1 和 V2 會以不同的方式處理空字串：
+ **V1**：將空字串轉換為 null 值，再傳送至 DynamoDB （無屬性）
+ **V2**：將空字串作為實際空字串值傳送至 DynamoDB

**重要**  
遷移至 V2 之後，如果您不希望在 DynamoDB 中存放空字串，則必須實作自訂轉換器。如果沒有自訂轉換器，V2 會將空字串儲存為 DynamoDB 項目中的實際空字串屬性，這與 V1 完全省略這些屬性的行為不同。

**Example 將空字串屬性轉換為 null 的 V2 自訂轉換器**  

```
/**
 * Custom converter that maintains V1 behavior by converting empty strings to null values
 * when writing to DynamoDB, ensuring compatibility with existing data. No attribute will be saved to DynamoDB.
 */
public class NullifyEmptyStringConverter implements AttributeConverter<String> {
    @Override
    public AttributeValue transformFrom(String value) {
        if (value == null || value.isEmpty()) {
            return AttributeValue.builder().nul(true).build();
        }
        return AttributeValue.builder().s(value).build();
    }

    @Override
    public String transformTo(AttributeValue attributeValue) {
        if (attributeValue.nul()) {
            return null;
        }
        return attributeValue.s();
    }

    @Override
    public EnhancedType<String> type() {
        return EnhancedType.of(String.class);
    }

    @Override
    public AttributeValueType attributeValueType() {
        return AttributeValueType.S;
    }
}

// V2 usage:
@DynamoDbBean
public class Customer {
    private String name;

    @DynamoDbConvertedBy(NullifyEmptyStringConverter.class)
    public String getName() {
        return name;
    }
}
```



# 適用於 Java 的 SDK 第 1 版和第 2 版之間的樂觀鎖定差異
<a name="dynamodb-migrate-optimstic-locking"></a>

V1 和 V2 都實作樂觀鎖定搭配屬性註釋，在您的 Bean 類別上標記一個屬性來存放版本號碼。


**樂觀鎖定行為的差異**  

|  | V1 | V2 | 
| --- | --- | --- | 
| Bean 類別註釋 | @DynamoDBVersionAttribute | @DynamoDbVersionAttribute （請注意，V2 使用小寫 "b") | 
| 初始儲存 | 版本編號屬性設定為 1。 |  使用 設定的版本屬性的起始值`@DynamoDbVersionAttribute(startAt = X)`。預設值為 0。  | 
| 更新 | 如果條件式檢查驗證要更新的物件版本編號符合資料庫中的編號，則版本編號屬性會遞增 1。 |  如果條件式檢查驗證要更新的物件版本編號符合資料庫中的編號，則版本編號屬性會遞增。 使用 設定`incrementBy`的選項遞增的版本編號屬性`@DynamoDbVersionAttribute(incrementBy = X)`。預設值為 1。  | 
| 刪除 | DynamoDBMapper 新增條件式檢查，確認要刪除之物件的版本編號符合資料庫中的版本編號。 |  V2 不會自動新增刪除操作的條件。如果您想要控制刪除行為，則必須手動新增條件表達式。 在下列範例中， `recordVersion`是 Bean 的版本屬性。 <pre>// 1. Read the item and get its current version.<br />Customer item = customerTable.getItem(Key.builder().partitionValue("someId").build());<br />AttributeValue currentVersion = item.getRecordVersion();<br /><br />// 2. Create conditional delete with the `currentVersion` value.<br />DeleteItemEnhancedRequest deleteItemRequest =<br />    DeleteItemEnhancedRequest.builder()<br />       .key(KEY)<br />       .conditionExpression(Expression.builder()<br />           .expression("recordVersion = :current_version_value")<br />           .putExpressionValue(":current_version_value", currentVersion)<br />           .build()).build();<br /><br />customerTable.deleteItem(deleteItemRequest);</pre>  | 
| 具有條件檢查的交易寫入 | 您無法在 addConditionCheck方法@DynamoDBVersionAttribute中使用以 標註的 Bean 類別。 | 您可以在transactWriteItems請求的addConditionCheck建置器方法中使用具有 @DynamoDbVersionAttribute註釋的 Bean 類別。 | 
| 停用 | 透過將 DynamoDBMapperConfig.SaveBehavior列舉值從 變更為 UPDATE來停用樂觀鎖定CLOBBER。 |  請勿使用 `@DynamoDbVersionAttribute`註釋。  | 

# 適用於 Java 的 SDK 第 1 版和第 2 版之間的流暢設定器差異
<a name="dynamodb-migrate-fluent-setters"></a>

您可以在適用於 V1 POJOs 搭配流暢的設定器，以及搭配自 2.30.29 版以來的 V2。 DynamoDB 

例如，下列 POJO 會從 `setName`方法傳回`Customer`執行個體：

```
// V1

@DynamoDBTable(tableName ="Customer")
public class Customer{
  private String name;
  // Other attributes and methods not shown.
  public Customer setName(String name){
     this.name = name;
     return this;
  }
}
```

不過，如果您使用 2.30.29 之前的 V2 版本， 會`setName`傳回`name`值為 的`Customer`執行個體`null`。

```
// V2 prior to version 2.30.29.

@DynamoDbBean
public class Customer{
  private String name;
  // Other attributes and methods not shown.
  public Customer setName(String name){ 
     this.name = name;
     return this;  // Bug: returns this instance with a `name` value of `null`.
  }
}
```

```
// Available in V2 since version 2.30.29.

@DynamoDbBean
public class Customer{
  private String name;
  // Other attributes and methods not shown.
  public Customer setName(String name){ 
     this.name = name;
     return this;  // Returns this instance for method chaining with the `name` value set.
  }
}
```

# 記錄 第 1 版和第 2 版之間的 API 差異 適用於 Java 的 AWS SDK
<a name="dynamodb-mapping-document-api"></a>

文件 API 支援使用 JSON 樣式的文件做為 DynamoDB 資料表中的單一項目。V1 文件 API 在 V2 中具有對應的 API，但 V1, V2 中一樣針對文件 API 使用單獨的用戶端。 DynamoDB 

在 V1 中， [https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/Item.html](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/Item.html)類別代表來自 DynamoDB 資料表的非結構化記錄。在 V2 中，非結構化記錄由 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html)類別的執行個體表示。請注意，主索引鍵是在 V2 的資料表結構描述中定義，以及在 V1 中的項目本身上定義。

下表比較 V1 和 V2 中文件 APIs之間的差異。


| 使用案例 | V1 | V2 | 
| --- |--- |--- |
| Create a document client |  <pre>AmazonDynamoDB client = ... //Create a client.<br />DynamoDB documentClient = new DynamoDB(client);</pre>  |  <pre>// The V2 Document API uses the same DynamoDbEnhancedClient<br />// that is used for mapping POJOs.<br />DynamoDbClient standardClient = ... //Create a standard client.<br />DynamoDbEnhancedClient enhancedClient = ... // Create an enhanced client.<br /></pre>  | 
| Reference a table |  <pre>Table documentTable = docClient.documentClient("Person");</pre>  |  <pre>DynamoDbTable<EnhancedDocument> documentTable = enhancedClient.table("Person",  <br />        TableSchema.documentSchemaBuilder()<br />              .addIndexPartitionKey(TableMetadata.primaryIndexName(),"id", AttributeValueType.S)<br />              .attributeConverterProviders(AttributeConverterProvider.defaultProvider())<br />              .build());</pre>  | 
| **Work with semi-structured data** | 
| --- |
| Put item |  <pre>Item item = new Item()<br />      .withPrimaryKey("id", 50)<br />      .withString("firstName", "Shirley");<br />PutItemOutcome outcome = documentTable.putItem(item);</pre>  |  <pre>EnhancedDocument personDocument = EnhancedDocument.builder()<br />        .putNumber("id", 50)<br />        .putString("firstName", "Shirley")<br />        .build();<br />documentTable.putItem(personDocument);</pre>  | 
| Get item |  <pre>GetItemOutcome outcome = documentTable.getItemOutcome( "id", 50);<br />Item personDocFromDb = outcome.getItem();<br />String firstName = personDocFromDb.getString("firstName");<br /></pre>  |  <pre>EnhancedDocument personDocFromDb = documentTable<br />        .getItem(Key.builder()<br />            .partitionValue(50)<br />            .build()); <br />String firstName = personDocFromDb.getString("firstName");<br /></pre>  | 
| **Work with JSON items** | 
| --- |
| Convert a JSON structure to use it with the Document API |  <pre>// The 'jsonPerson' identifier is a JSON string. <br />Item item = new Item().fromJSON(jsonPerson);</pre>  |  <pre>// The 'jsonPerson' identifier is a JSON string.<br />EnhancedDocument document = EnhancedDocument.builder()<br />        .json(jsonPerson).build());</pre>  | 
| Put JSON |  <pre>documentTable.putItem(item)</pre>  |  <pre>documentTable.putItem(document);</pre>  | 
| Read JSON |  <pre>GetItemOutcome outcome = //Get item.<br />String jsonPerson = outcome.getItem().toJSON();</pre>  |  <pre>String jsonPerson = documentTable.getItem(Key.builder()<br />        .partitionValue(50).build())<br />        .fromJson();</pre>  | 

## 文件 API APIs 參考和指南
<a name="dynamodb-mapping-document-api-ref"></a>


|  | V1 | V2 | 
| --- | --- | --- | 
| API 參考 | [API 參考](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/package-summary.html) | [API 參考](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/package-summary.html) | 
| 文件指南 | 《Amazon DynamoDB 開發人員指南》[https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/JavaDocumentAPIItemCRUD.html](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/JavaDocumentAPIItemCRUD.html) | [增強型文件 API](ddb-en-client-doc-api.md) （本指南） | 

# V1 Xpec API 至 V2 表達式 API
<a name="ddb-v1-xspec-migrate"></a>

V1 中可用的表達式規格 (Xspec) API，可協助建立表達式以使用 V2 中的文件導向資料。V2 使用表達式 API，可處理文件導向資料和object-to-item映射資料。


****  

|  | V1 | V2 | 
| --- | --- | --- | 
| API 名稱 | 表達式規格 (Xspec) API | 表達式 API | 
| 使用 | 文件 API [資料表](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/Table.html)類別的方法，例如 [updateItem](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/Table.html#updateItem-java.lang.String-java.lang.Object-com.amazonaws.services.dynamodbv2.xspec.UpdateItemExpressionSpec-) 和[掃描](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/Table.html#scan-com.amazonaws.services.dynamodbv2.xspec.ScanExpressionSpec-) |  DynamoDB 增強型用戶端APIs： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/ddb-v1-xspec-migrate.html) 對於這兩種類型的 APIs，在您取得[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html)執行個體之後： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/ddb-v1-xspec-migrate.html) 當您建立請求物件時，您會在 `DynamoDbTable` 方法中使用表達式。例如，在 的 `filterExpression`方法中 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryEnhancedRequest.Builder.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryEnhancedRequest.Builder.html)  | 
| Resources |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-java/latest/developer-guide/ddb-v1-xspec-migrate.html)  | 本 Java 開發人員指南中的[表達式資訊](ddb-en-client-expressions.md)  | 

# 加密程式庫遷移
<a name="ddb-encryption-lib-migrate"></a>

如需遷移 DynamoDB 加密程式庫以使用 Java 開發套件 V2 的相關資訊，請參閱 [Amazon DynamoDB 加密用戶端開發人員指南](https://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/ddb-java-migrate.html)。

# 從第 1 版到第 2 版的自動 Amazon SQS 請求批次變更
<a name="migration-sqs-auto-batching"></a>

本主題詳細說明 第 1 版和第 2 版之間的 Amazon SQS 自動請求批次處理變更 適用於 Java 的 AWS SDK。

## 高階變更
<a name="migration-sqs-auto-batching-high-level-changes"></a>

 適用於 Java 的 AWS SDK 1.x 會使用需要明確初始化請求批次的個別`[AmazonSQSBufferedAsyncClient](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/sqs/buffered/AmazonSQSBufferedAsyncClient.html)`類別來執行用戶端緩衝。

使用 AWS SDK for Java 2.x 簡化和增強緩衝功能`[SqsAsyncBatchManager](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.html)`。此界面的實作提供與標準 直接整合的自動請求批次處理功能`[SqsAsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/SqsAsyncClient.html)`。若要了解 v2 的 `SqsAsyncBatchManager`，請參閱本指南中的 [搭配 使用 Amazon SQS 的自動請求批次處理 AWS SDK for Java 2.x](sqs-auto-batch.md)主題。


| 變更 | v1 |   v2 | 
| --- | --- | --- | 
|    Maven 相依性  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>com.amazonaws</groupId><br />            <artifactId>aws-java-sdk-bom</artifactId><br />            <version>1.12.7821</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-java-sdk-sqs</artifactId><br />    </dependency><br /></dependencies><br /></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.31.152</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>sqs</artifactId><br />    </dependency><br /></dependencies></pre>  | 
| 套件名稱 | com.amazonaws.services.sqs.buffered | software.amazon.awssdk.services.sqs.batchmanager | 
| 類別名稱 |  `[AmazonSQSBufferedAsyncClient](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/sqs/buffered/AmazonSQSBufferedAsyncClient.html)`  | [SqsAsyncBatchManager](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.html) | 

1 [最新版本](https://central.sonatype.com/artifact/com.amazonaws/aws-java-sdk-bom)。 2 [最新版本](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)。

## 使用自動 SQS 請求批次處理
<a name="migration-sqs-auto-batching-using"></a>


| 變更 | v1 |   v2 | 
| --- | --- | --- | 
| 建立批次管理工具 |  <pre>AmazonSQSAsync sqsAsync = new AmazonSQSAsyncClient();<br />AmazonSQSAsync bufferedSqs = new <br />            AmazonSQSBufferedAsyncClient(sqsAsync);</pre>  |  <pre>SqsAsyncClient asyncClient = SqsAsyncClient.create();<br />SqsAsyncBatchManager sqsAsyncBatchManager = <br />            asyncClient.batchManager();</pre>  | 
| 建立具有自訂組態的批次管理工具 |  <pre>AmazonSQSAsync sqsAsync = new AmazonSQSAsyncClient();<br /><br />QueueBufferConfig queueBufferConfig = new QueueBufferConfig()<br />        .withMaxBatchOpenMs(200)<br />        .withMaxBatchSize(10)<br />        .withMinReceiveWaitTimeMs(1000)<br />        .withVisibilityTimeoutSeconds(20)<br />        .withReceiveMessageAttributeNames(messageAttributeValues);<br /><br />AmazonSQSAsync bufferedSqs = <br />        new AmazonSQSBufferedAsyncClient(sqsAsync, queueBufferConfig);</pre>  |  <pre>BatchOverrideConfiguration batchOverrideConfiguration = <br />    BatchOverrideConfiguration.builder()<br />        .sendRequestFrequency(Duration.ofMillis(200))<br />        .maxBatchSize(10)<br />        .receiveMessageMinWaitDuration(Duration.ofMillis(1000))<br />        .receiveMessageVisibilityTimeout(Duration.ofSeconds(20))<br />        .receiveMessageSystemAttributeNames(messageSystemAttributeNames)<br />        .receiveMessageAttributeNames(messageAttributeValues)<br />        .build();<br /><br />SqsAsyncBatchManager sqsAsyncBatchManager = SqsAsyncBatchManager.builder()<br />        .overrideConfiguration(batchOverrideConfiguration)<br />        .client(SqsAsyncClient.create())<br />        .scheduledExecutor(Executors.newScheduledThreadPool(8))<br />        .build();</pre>  | 
| 傳送訊息 |  <pre>Future<SendMessageResult> sendResultFuture = <br />        bufferedSqs.sendMessageAsync(new SendMessageRequest()<br />                .withQueueUrl(queueUrl)<br />                .withMessageBody(body));</pre>  |  <pre>CompletableFuture<SendMessageResponse> sendCompletableFuture = <br />        sqsAsyncBatchManager.sendMessage(<br />                SendMessageRequest.builder()<br />                        .queueUrl(queueUrl)<br />                        .messageBody(body)<br />                        .build());</pre>  | 
| 刪除訊息 |  <pre>Future<DeleteMessageResult> deletResultFuture =<br />        bufferedSqs.deleteMessageAsync(new DeleteMessageRequest()<br />                .withQueueUrl(queueUrl));</pre>  |  <pre>CompletableFuture<DeleteMessageResponse> deleteResultCompletableFuture<br />        = sqsAsyncBatchManager.deleteMessage(<br />                DeleteMessageRequest.builder()<br />                        .queueUrl(queueUrl)<br />                        .build());</pre>  | 
| 變更訊息的可見性 |  <pre>Future<ChangeMessageVisibilityResult> changeVisibilityResultFuture =<br />        bufferedSqs.changeMessageVisibilityAsync<br />                (new ChangeMessageVisibilityRequest()<br />                        .withQueueUrl(queueUrl)<br />                        .withVisibilityTimeout(20));</pre>  |  <pre>CompletableFuture<ChangeMessageVisibilityResponse> changeResponseCompletableFuture<br />        = sqsAsyncBatchManager.changeMessageVisibility(<br />                ChangeMessageVisibilityRequest.builder()<br />                        .queueUrl(queueUrl)<br />                        .visibilityTimeout(20)<br />                        .build());</pre>  | 
| 接收訊息 |  <pre>ReceiveMessageResult receiveResult =<br />        bufferedSqs.receiveMessage(<br />                new ReceiveMessageRequest()<br />                        .withQueueUrl(queueUrl));</pre>  |  <pre>CompletableFuture<ReceiveMessageResponse> <br />        responseCompletableFuture = sqsAsyncBatchManager.receiveMessage(<br />                ReceiveMessageRequest.builder()<br />                        .queueUrl(queueUrl)<br />                        .build());</pre>  | 

## 非同步傳回類型差異
<a name="migration-sqs-auto-batching-asyc-return-type"></a>


| 變更 | v1 |   v2 | 
| --- | --- | --- | 
| 傳回類型 | Future<ResultType> | CompletableFuture<ResponseType> | 
| 回呼機制 | 需要AsyncHandler具有個別 onSuccess和 onError方法的 | 使用 JDK 提供的 CompletableFuture APIs，例如 whenComplete()、thenCompose()、 thenApply() | 
| 例外狀況處理 | 使用 AsyncHandler\$1onError() 方法 | 使用 JDK 提供的 CompletableFuture APIs，例如 exceptionally()、 handle()或 whenComplete() | 
| Cancellation | 透過 的基本支援 Future.cancel() | 取消父系CompletableFuture會自動取消鏈結中的所有相依未來 | 

## 非同步完成處理差異
<a name="migration-sqs-auto-batching-asyc-completion-handling"></a>


| 變更 | v1 |   v2 | 
| --- | --- | --- | 
| 回應處理常式實作 |  <pre>Future<ReceiveMessageResult> future = bufferedSqs.receiveMessageAsync(<br />        receiveRequest,<br />        new AsyncHandler<ReceiveMessageRequest, ReceiveMessageResult>() {<br />            @Override<br />            public void onSuccess(ReceiveMessageRequest request, <br />                              ReceiveMessageResult result) {<br />                List<Message> messages = result.getMessages();<br />                System.out.println("Received " + messages.size() + " messages");<br />                for (Message message : messages) {<br />                    System.out.println("Message ID: " + message.getMessageId());<br />                    System.out.println("Body: " + message.getBody());<br />                }<br />            }<br /><br />            @Override<br />            public void onError(Exception e) {<br />                System.err.println("Error receiving messages: " + e.getMessage());<br />                e.printStackTrace();<br />            }<br />        }<br />);</pre>  |  <pre>CompletableFuture<ReceiveMessageResponse> completableFuture = sqsAsyncBatchManager<br />               .receiveMessage(ReceiveMessageRequest.builder()<br />               .queueUrl(queueUrl).build())<br />        .whenComplete((receiveMessageResponse, throwable) -> {<br />            if (throwable != null) {<br />                System.err.println("Error receiving messages: " + throwable.getMessage());<br />                throwable.printStackTrace();<br />            } else {<br />                List<Message> messages = receiveMessageResponse.messages();<br />                System.out.println("Received " + messages.size() + " messages");<br />                for (Message message : messages) {<br />                    System.out.println("Message ID: " + message.messageId());<br />                    System.out.println("Body: " + message.body());<br />                }<br />            }<br />        });</pre>  | 

## 金鑰組態參數
<a name="migration-sqs-auto-batching-params"></a>


****  

| 參數 | v1 |   v2 | 
| --- | --- | --- | 
| 最大批次大小 | maxBatchSize （每個批次預設 10 個請求） | maxBatchSize （每個批次預設 10 個請求） | 
| 批次等待時間 | maxBatchOpenMs （預設 200 毫秒） | sendRequestFrequency （預設 200 毫秒） | 
| 可見性逾時 | visibilityTimeoutSeconds （佇列預設值為 -1) | receiveMessageVisibilityTimeout （佇列預設值） | 
| 最短等待時間 | longPollWaitTimeoutSeconds (20 秒，若 longPoll為 true) | receiveMessageMinWaitDuration （預設 50 毫秒） | 
| 訊息屬性 | 使用 設定 ReceiveMessageRequest | receiveMessageAttributeNames （預設為無） | 
| 系統屬性 | 使用 設定 ReceiveMessageRequest | receiveMessageSystemAttributeNames （預設為無） | 
| 長輪詢 | longPoll （預設值為 true) | 不支援以避免開放連線等待伺服器傳送訊息 | 
| 長輪詢的等待時間上限 | longPollWaitTimeoutSeconds （預設 20 秒） | 不支援以避免開放連線等待伺服器傳送訊息 | 
| 儲存用戶端的預先擷取接收批次數目上限 | maxDoneReceiveBatches (10 個批次） | 不支援，因為它是在內部處理 | 
| 同時處理的作用中傳出批次數量上限 | maxInflightOutboundBatches （預設 5 個批次） | 不支援，因為它是在內部處理 | 
| 同時處理的作用中接收批次數量上限 | maxInflightReceiveBatches （預設 10 個批次） | 不支援，因為它是在內部處理 | 

# side-by-side使用適用於 Java 的 開發套件 1.x 和 2.x
<a name="migration-side-by-side"></a>

您可以在專案 適用於 Java 的 AWS SDK 中使用 的兩個版本。

以下顯示 Amazon S3 使用 1.x 版和 1.x 版 的 專案`pom.xml`檔案範例 ，以及 DynamoDB 使用 的 版本 - 2.27.21 1.2 版 - 的 。

**Example 範例 POM**  
此範例顯示同時使用 SDK 1.x 和 2.x 版本的專案`pom.xml`的檔案項目。  

```
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-bom</artifactId>
            <version>1.12.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
          <groupId>software.amazon.awssdk</groupId>
          <artifactId>bom</artifactId>
          <version>2.27.21</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-java-sdk-s3</artifactId>
    </dependency>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>dynamodb</artifactId>
    </dependency>
</dependencies>
```