

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

# 使用 S3 事件通知
<a name="examples-s3-event-notifications"></a>

為了協助您監控儲存貯體中的活動，Amazon S3 可以在發生特定事件時傳送通知。Amazon S3 使用者指南提供[儲存貯體可傳送之通知](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventNotifications.html#notification-how-to-overview)的相關資訊。

您可以使用適用於 Java 的 SDK 設定儲存貯體，將事件傳送至四個可能的目的地：
+ Amazon Simple Notification Service 主題
+ Amazon Simple Queue Service 佇列
+ AWS Lambda 函數
+ Amazon EventBridge

當您設定儲存貯體將事件傳送至 EventBridge 時，您可以設定 EventBridge 規則，將相同的事件散發到多個目的地。當您將儲存貯體設定為直接傳送至前三個目的地之一時，每個事件只能指定一個目的地類型。

在下一節中，您將了解如何使用適用於 Java 的 SDK 設定儲存貯體，以兩種方式傳送 S3 事件通知：直接傳送至 Amazon SQS 佇列和 EventBridge。

最後一節說明如何使用 S3 事件通知 API，以物件導向的方式使用通知。

## 設定儲存貯體以直接傳送至目的地
<a name="s3-event-conf-bucket-direct"></a>

下列範例會設定儲存貯體，以在*物件建立*事件或*物件標記*事件發生時傳送通知。

```
static void processS3Events(String bucketName, String queueArn) {
    // Configure the bucket to send Object Created and Object Tagging notifications to an existing SQS queue.
    s3Client.putBucketNotificationConfiguration(b -> b
            .notificationConfiguration(ncb -> ncb
                    .queueConfigurations(qcb -> qcb
                            .events(Event.S3_OBJECT_CREATED, Event.S3_OBJECT_TAGGING)
                            .queueArn(queueArn)))
                    .bucket(bucketName)
    );
}
```

上面顯示的程式碼會設定一個佇列來接收兩種類型的事件。方便使用， `queueConfigurations`方法可讓您視需要設定多個佇列目的地。此外，您可以在 `notificationConfiguration`方法中設定其他目的地，例如一或多個 Amazon SNS 主題或一或多個 Lambda 函數。下列程式碼片段顯示具有兩個佇列和三種目的地類型的範例。

```
s3Client.putBucketNotificationConfiguration(b -> b
                .notificationConfiguration(ncb -> ncb
                        .queueConfigurations(qcb -> qcb
                                .events(Event.S3_OBJECT_CREATED, Event.S3_OBJECT_TAGGING)
                                .queueArn(queueArn), 
                                qcb2 -> qcb2.<...>)
                        .topicConfigurations(tcb -> tcb.<...>)
                        .lambdaFunctionConfigurations(lfcb -> lfcb.<...>))
                        .bucket(bucketName)
        );
```

程式碼範例 GitHub 儲存庫包含將 S3 事件通知直接傳送到佇列[的完整範例](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/ProcessS3EventNotification.java)。

## 設定要傳送至 EventBridge 的儲存貯體
<a name="s3-event-conf-bucket-eventbridge"></a>

下列範例會將儲存貯體設定為傳送通知至 EventBridge。

```
public static String setBucketNotificationToEventBridge(String bucketName) {
    // Enable bucket to emit S3 Event notifications to EventBridge.
    s3Client.putBucketNotificationConfiguration(b -> b
            .bucket(bucketName)
            .notificationConfiguration(b1 -> b1
                    .eventBridgeConfiguration(SdkBuilder::build))
    .build());
```

當您設定儲存貯體將事件傳送至 EventBridge 時，您只需指出 EventBridge 目的地，而不是 EventBridge 將發送的事件類型或最終目的地。您可以使用 Java 開發套件的 EventBridge 用戶端來設定最終目標和事件類型。

下列程式碼說明如何設定 EventBridge 將*物件建立*的事件散發至主題和佇列。

```
   public static String configureEventBridge(String topicArn, String queueArn) {
        try {
            // Create an EventBridge rule to route Object Created notifications.
            PutRuleRequest putRuleRequest = PutRuleRequest.builder()
                    .name(RULE_NAME)
                    .eventPattern("""
                            {
                              "source": ["aws.s3"],
                              "detail-type": ["Object Created"],
                              "detail": {
                                "bucket": {
                                  "name": ["%s"]
                                }
                              }
                            }
                            """.formatted(bucketName))
                    .build();

            // Add the rule to the default event bus.
            PutRuleResponse putRuleResponse = eventBridgeClient.putRule(putRuleRequest)
                    .whenComplete((r, t) -> {
                        if (t != null) {
                            logger.error("Error creating event bus rule: " + t.getMessage(), t);
                            throw new RuntimeException(t.getCause().getMessage(), t);
                        }
                        logger.info("Event bus rule creation request sent successfully. ARN is: {}", r.ruleArn());
                    }).join();

            // Add the existing SNS topic and SQS queue as targets to the rule.
            eventBridgeClient.putTargets(b -> b
                    .eventBusName("default")
                    .rule(RULE_NAME)
                    .targets(List.of (
                            Target.builder()
                                    .arn(queueArn)
                                    .id("Queue")
                                    .build(),
                            Target.builder()
                                    .arn(topicArn)
                                    .id("Topic")
                                    .build())
                            )
                    ).join();
            return putRuleResponse.ruleArn();
        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return null;
    }
```

若要在 Java 程式碼中使用 EventBridge，請將`eventbridge`成品的相依性新增至 Maven `pom.xml` 檔案。

```
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>eventbridge</artifactId>
</dependency>
```

程式碼範例 GitHub 儲存庫包含傳送 S3 事件通知至 EventBridge，然後傳送至主題和佇列[的完整範例](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/PutBucketS3EventNotificationEventBridge.java)。

## 使用 S3 事件通知 API 來處理事件
<a name="s3-event-notification-read"></a>

目的地收到 S3 通知事件後，您可以使用 S3 事件通知 API，以物件導向的方式處理它們。您可以使用 S3 事件通知 API 來處理直接分派至目標的事件通知 （如[第一個範例](#s3-event-conf-bucket-direct)所示），但不適用於透過 EventBridge 路由的通知。儲存貯體傳送至 EventBridge 的 S3 事件通知包含 S3 事件通知 API 目前未處理[的不同結構](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ev-events.html#ev-events-list)。

### 新增相依性
<a name="s3-event-notifications-dep"></a>

S3 事件通知 API 已搭配適用於 Java 的 SDK 2.x 2.25.11 版發行。

若要使用 S3 事件通知 API，請將必要的相依性元素新增至 Maven`pom.xml`，如下列程式碼片段所示。

```
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bom</artifactId>
            <version>2.X.X1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3-event-notifications</artifactId>
    </dependency>
</dependencies>
```

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

### 使用 `S3EventNotification`類別
<a name="s3-event-notifications-use"></a>

#### 從 JSON 字串建立`S3EventNotification`執行個體
<a name="s3-event-notifications-use-from-json"></a>

若要將 JSON 字串轉換為`S3EventNotification`物件，請使用 `S3EventNotification`類別的靜態方法，如下列範例所示。

```
import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification
import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord
import software.amazon.awssdk.services.sqs.model.Message; 

public class S3EventNotificationExample {
    ...
    
    void receiveMessage(Message message) {
       // Message received from SQSClient.
       String sqsEventBody = message.body();
       S3EventNotification s3EventNotification = S3EventNotification.fromJson(sqsEventBody);
    
       // Use getRecords() to access all the records in the notification.                                                                                                       
       List<S3EventNotificationRecord> records = s3EventNotification.getRecords();   
    
        S3EventNotificationRecord record = records.stream().findFirst();
        // Use getters on the record to access individual attributes.
        String awsRegion = record.getAwsRegion();
        String eventName = record.getEventName();
        String eventSource = record.getEventSource();                                                                                                   
    }
}
```

在此範例中， `fromJson`方法會將 JSON 字串轉換為 `S3EventNotification` 物件。JSON 字串中缺少的欄位會導致對應 Java 物件欄位中`null`的值，且 JSON 中的任何額外欄位都會遭到忽略。

您可以在 APIs 參考中找到事件通知記錄的其他 API`[S3EventNotificationRecord](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/S3EventNotificationRecord.html)`。

#### 將`S3EventNotification`執行個體轉換為 JSON 字串
<a name="s3-event-notifications-use-to-json"></a>

使用 `toJson`（或 `toJsonPretty`) 方法將`S3EventNotification`物件轉換為 JSON 字串，如下列範例所示。

```
import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification

public class S3EventNotificationExample {
    ...

    void toJsonString(S3EventNotification event) {

        String json = event.toJson();
        String jsonPretty = event.toJsonPretty();

        System.out.println("JSON: " + json);
        System.out.println("Pretty JSON: " + jsonPretty);
    }
}
```

如果 `GlacierEventData`、`IntelligentTieringEventData`、 `ReplicationEventData`和 的欄位是 ，`LifecycleEventData`則會從 JSON 中排除`null`。其他`null`欄位將序列化為 `null`。

以下顯示 S3 物件標記事件的 `toJsonPretty`方法輸出範例。

```
{
  "Records" : [ {
    "eventVersion" : "2.3",
    "eventSource" : "aws:s3",
    "awsRegion" : "us-east-1",
    "eventTime" : "2024-07-19T20:09:18.551Z",
    "eventName" : "ObjectTagging:Put",
    "userIdentity" : {
      "principalId" : "AWS:XXXXXXXXXXX"
    },
    "requestParameters" : {
      "sourceIPAddress" : "XXX.XX.XX.XX"
    },
    "responseElements" : {
      "x-amz-request-id" : "XXXXXXXXXXXX",
      "x-amz-id-2" : "XXXXXXXXXXXXX"
    },
    "s3" : {
      "s3SchemaVersion" : "1.0",
      "configurationId" : "XXXXXXXXXXXXX",
      "bucket" : {
        "name" : "amzn-s3-demo-bucket",
        "ownerIdentity" : {
          "principalId" : "XXXXXXXXXXX"
        },
        "arn" : "arn:aws:s3:::XXXXXXXXXX"
      },
      "object" : {
        "key" : "akey",
        "size" : null,
        "eTag" : "XXXXXXXXXX",
        "versionId" : null,
        "sequencer" : null
      }
    }
  } ]
}
```

GitHub 提供[完整的範例](https://github.com/awsdocs/aws-doc-sdk-examples/blob/75c3daadf750406156fc87fa30ee499a206b4a36/javav2/example_code/s3/src/main/java/com/example/s3/ProcessS3EventNotification.java#L117)，說明如何使用 API 來處理 Amazon SQS 佇列收到的通知。

## 使用 Java 程式庫處理 Lambda 中的 S3 事件： AWS SDK for Java 2.x 和 `aws-lambda-java-events`
<a name="s3-event-notif-processing-options"></a>

與其使用適用於 Java 的 SDK 2.x 在 Lambda 函數中處理 Amazon S3 事件通知，您可以在 3.x.x 版使用`[aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events)`程式庫。 會獨立 AWS 維護`aws-lambda-java-events`程式庫，並且具有自己的相依性要求。`aws-lambda-java-events` 程式庫僅適用於 Lambda 函數中的 S3 事件，而適用於 Java 的 SDK 2.x 僅適用於 Lambda 函數、Amazon SNS 和 Amazon SQS 中的 S3 事件。

這兩種方法都使用類似的 APIs，以物件導向的方式建立 JSON 事件通知承載的模型。下表顯示使用兩種方法之間的顯著差異。


****  

|  | 適用於 Java 的 AWS SDK | aws-lambda-java-events 程式庫 | 
| --- | --- | --- | 
| 套件命名 |  `software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification`  | com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification | 
| RequestHandler 參數 |  撰寫 Lambda 函數的`RequestHandler`實作以接收 JSON 字串： <pre>import com.amazonaws.services.lambda.runtime.Context;<br />import com.amazonaws.services.lambda.runtime.RequestHandler;<br />import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;<br /><br />public class Handler implements RequestHandler<String, String> {<br /><br />    @Override<br />        public String handleRequest(String jsonS3Event, Context context) {<br />            S3EventNotification s3Event = S3EventNotification<br />                                             .fromJson(jsonS3Event);<br />            // Work with the s3Event object.        <br />            ...<br />    }<br />}</pre>  | 撰寫 Lambda 函數的RequestHandler實作以接收S3Event物件：<pre>import com.amazonaws.services.lambda.runtime.Context;<br />import com.amazonaws.services.lambda.runtime.RequestHandler;<br />import com.amazonaws.services.lambda.runtime.events.S3Event;<br /><br />public class Handler implements RequestHandler<S3Event, String> {<br /><br />    @Override<br />        public String handleRequest(S3Event s3event, Context context) {<br />            // Work with the s3Event object.        <br />            ...<br />    }<br />}</pre> | 
| Maven 相依性 |  <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 /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>s3-event-notifications</artifactId><br />    </dependency><br />    <!-- Add other SDK dependencies that you need. --><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 /><dependencies><br />    <!-- The following two dependencies are for the <br />         aws-lambda-java-events library. --><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-lambda-java-core</artifactId><br />        <version>1.2.3</version>     <br />    </dependency><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-lambda-java-events</artifactId><br />        <version>3.15.0</version><br />    </dependency><br />    <!-- Add other SDK dependencies that you need. --><br /></dependencies></pre>  | 