

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

# Amazon SQS Java SDK 示例
<a name="sqs-java-tutorials"></a>

适用于 Java 的 AWS SDK 支持您构建与 Amazon SQS 及其他 AWS 服务交互的 Java 应用程序。
+ 要安装和设置 SDK，请参阅《AWS SDK for Java 2.x 开发人员指南》**中的[开始使用](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/getting-started.html)。
+ 有关基本队列操作（例如创建队列或发送消息），请参阅《AWS SDK for Java 2.x 开发人员指南》**中的[使用 Amazon SQS 消息队列](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/sqs-examples.html)。
+ 该指南还包括其他 Amazon SQS 功能的示例，例如：
  + [在 Amazon SQS 队列中使用服务器端加密](sqs-java-configure-sse.md)
  + [为 Amazon SQS 队列配置标签](sqs-java-add-update-remove-tag-queue.md)
  + [将消息属性发送到 Amazon SQS 队列](sqs-java-send-message-with-attributes.md)

# 在 Amazon SQS 队列中使用服务器端加密
<a name="sqs-java-configure-sse"></a>

使用 适用于 Java 的 AWS SDK 将服务器端加密 (SSE) 添加到 Amazon SQS 队列。每个队列都使用 AWS Key Management Service (AWS KMS) KMS 密钥生成数据加密密钥。此示例设置 AWS 托管 KMS 密钥用于 Amazon SQS。

有关使用 SSE 和 KMS 密钥角色的更多信息，请参阅[Amazon SQS 中的静态加密](sqs-server-side-encryption.md)。

## 向现有队列添加 SSE
<a name="sqs-java-configure-sse-existing-queue"></a>

要为现有队列启用服务器端加密，请使用 `[SetQueueAttributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html)` 方法设置 `KmsMasterKeyId` 属性。

以下代码示例将设置 AWS KMS key 为 Amazon SQS 的 AWS 托管 KMS 密钥。该示例还会将 [AWS KMS key 重用周期](sqs-server-side-encryption.md#sqs-sse-key-terms)设置为 140 秒。

 在运行示例代码之前，请确保已设置 AWS 凭据。有关更多信息，请参阅《*AWS SDK for Java 2.x 开发人员指南》中的设置开发 AWS *[凭证和区域](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials)。

```
    public static void addEncryption(String queueName, String kmsMasterKeyAlias) {
        SqsClient sqsClient = SqsClient.create();

        GetQueueUrlRequest urlRequest = GetQueueUrlRequest.builder()
                .queueName(queueName)
                .build();

        GetQueueUrlResponse getQueueUrlResponse;
        try {
            getQueueUrlResponse = sqsClient.getQueueUrl(urlRequest);
        } catch (QueueDoesNotExistException e) {
            LOGGER.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
        String queueUrl = getQueueUrlResponse.queueUrl();


        Map<QueueAttributeName, String> attributes = Map.of(
                QueueAttributeName.KMS_MASTER_KEY_ID, kmsMasterKeyAlias,
                QueueAttributeName.KMS_DATA_KEY_REUSE_PERIOD_SECONDS, "140" // Set the data key reuse period to 140 seconds.
        );                                                                  // This is how long SQS can reuse the data key before requesting a new one from KMS.

        SetQueueAttributesRequest attRequest = SetQueueAttributesRequest.builder()
                .queueUrl(queueUrl)
                .attributes(attributes)
                .build();
        try {
            sqsClient.setQueueAttributes(attRequest);
            LOGGER.info("The attributes have been applied to {}", queueName);
        } catch (InvalidAttributeNameException | InvalidAttributeValueException e) {
            LOGGER.error(e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            sqsClient.close();
        }
    }
```

## 为队列禁用 SSE
<a name="sqs-java-disable-sse"></a>

要为现有队列禁用服务器端加密，请使用 `SetQueueAttributes` 方法将 `KmsMasterKeyId` 属性设置为空字符串。

**重要**  
`null` 对于 `KmsMasterKeyId` 是无效值。

## 使用 SSE 创建队列
<a name="sqs-java-configure-sse-create-queue"></a>

要在创建队列时启用 SSE，请将 `KmsMasterKeyId` 属性添加到 `[CreateQueue](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html)` API 方法中。

以下示例将在启用了 SSE 的情况下创建新队列。队列将 AWS 托管 KMS 密钥用于 Amazon SQS。该示例还会将 [AWS KMS key 重用周期](sqs-server-side-encryption.md#sqs-sse-key-terms)设置为 160 秒。

 在运行示例代码之前，请确保已设置 AWS 凭据。有关更多信息，请参阅《*AWS SDK for Java 2.x 开发人员指南》中的设置开发 AWS *[凭证和区域](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials)。

```
// Create an SqsClient for the specified Region.
SqsClient sqsClient = SqsClient.builder().region(Region.US_WEST_1).build();

// Create a hashmap for the attributes. Add the key alias and reuse period to the hashmap.
HashMap<QueueAttributeName, String> attributes = new HashMap<QueueAttributeName, String>();
final String kmsMasterKeyAlias = "alias/aws/sqs";  // the alias of the AWS managed KMS key for Amazon SQS.
attributes.put(QueueAttributeName.KMS_MASTER_KEY_ID, kmsMasterKeyAlias);
attributes.put(QueueAttributeName.KMS_DATA_KEY_REUSE_PERIOD_SECONDS, "140");				

// Add the attributes to the CreateQueueRequest.
CreateQueueRequest createQueueRequest =
                CreateQueueRequest.builder()
                        .queueName(queueName)
                        .attributes(attributes)
                        .build();
sqsClient.createQueue(createQueueRequest);
```

## 检索 SSE 属性
<a name="sqs-java-get-sse-attributes"></a>

有关检索队列属性的信息，请参阅 *Amazon Simple Queue Service API 参考*中的[示例](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_GetQueueAttributes.html#API_GetQueueAttributes_Examples)。

要检索特定队列的 KMS 密钥 ID 或数据密钥重用周期，请运行 `[GetQueueAttributes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_GetQueueAttributes.html)` 方法并检索 `KmsMasterKeyId` 和 `KmsDataKeyReusePeriodSeconds` 值。

# 为 Amazon SQS 队列配置标签
<a name="sqs-java-add-update-remove-tag-queue"></a>

使用 cost-allocation 标签来帮助组织和标识 Amazon SQS 队列。以下示例演示如何使用 适用于 Java 的 AWS SDK来配置标签。有关更多信息，请参阅 [Amazon SQS 成本分配标签](sqs-queue-tags.md)。

 在运行示例代码之前，请确保已设置 AWS 凭据。有关更多信息，请参阅《*AWS SDK for Java 2.x 开发人员指南》中的设置开发 AWS *[凭证和区域](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials)。

## 列出标签
<a name="sqs-java-list-tags"></a>

要列出队列的标签，请使用 `ListQueueTags` 方法。

```
// Create an SqsClient for the specified region.
SqsClient sqsClient = SqsClient.builder().region(Region.US_WEST_1).build();

// Get the queue URL.
String queueName = "MyStandardQ1";
GetQueueUrlResponse getQueueUrlResponse =
        sqsClient.getQueueUrl(GetQueueUrlRequest.builder().queueName(queueName).build());
String queueUrl = getQueueUrlResponse.queueUrl();

// Create the ListQueueTagsRequest.
final ListQueueTagsRequest listQueueTagsRequest = 
                                  ListQueueTagsRequest.builder().queueUrl(queueUrl).build();

// Retrieve the list of queue tags and print them.
final ListQueueTagsResponse listQueueTagsResponse =
                                  sqsClient.listQueueTags(listQueueTagsRequest);
System.out.println(String.format("ListQueueTags: \tTags for queue %s are %s.\n",
                queueName, listQueueTagsResponse.tags() ));
```

## 添加或更新标签
<a name="sqs-java-add-tags"></a>

要为队列添加或更新标签值，请使用 `TagQueue` 方法。

```
 // Create an SqsClient for the specified Region.
SqsClient sqsClient = SqsClient.builder().region(Region.US_WEST_1).build();

// Get the queue URL.
String queueName = "MyStandardQ1";
GetQueueUrlResponse getQueueUrlResponse =
        sqsClient.getQueueUrl(GetQueueUrlRequest.builder().queueName(queueName).build());
String queueUrl = getQueueUrlResponse.queueUrl();	

// Build a hashmap of the tags.
final HashMap<String, String> addedTags = new HashMap<>();
        addedTags.put("Team", "Development");
        addedTags.put("Priority", "Beta");
        addedTags.put("Accounting ID", "456def");

//Create the TagQueueRequest and add them to the queue.
final TagQueueRequest tagQueueRequest = TagQueueRequest.builder()
        .queueUrl(queueUrl)
        .tags(addedTags)
        .build();
sqsClient.tagQueue(tagQueueRequest);
```

## 移除标签
<a name="sqs-java-remove-tags"></a>

要从队列中删除一个或多个标签，请使用 `UntagQueue` 方法。以下示例将删除 `Accounting ID` 标签。

```
 
// Create the UntagQueueRequest.
final UntagQueueRequest untagQueueRequest = UntagQueueRequest.builder()
        .queueUrl(queueUrl)
        .tagKeys("Accounting ID")
        .build();
        
// Remove the tag from this queue.
sqsClient.untagQueue(untagQueueRequest);
```

# 将消息属性发送到 Amazon SQS 队列
<a name="sqs-java-send-message-with-attributes"></a>

您可以使用*消息属性*，在消息中包括结构化元数据（如时间戳、地理空间数据、签名和标识符）。有关更多信息，请参阅 [Amazon SQS 消息属性](sqs-message-metadata.md#sqs-message-attributes)。

 在运行示例代码之前，请确保已设置 AWS 凭据。有关更多信息，请参阅《*AWS SDK for Java 2.x 开发人员指南》中的设置开发 AWS *[凭证和区域](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials)。

## 定义属性
<a name="sqs-java-define-attributes"></a>

要为消息定义属性，请添加使用 `[MessageAttributeValue](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_MessageAttributeValue.html)` 数据类型的以下代码。有关更多信息，请参阅[消息属性组件](sqs-message-metadata.md#message-attribute-components)和[消息属性数据类型](sqs-message-metadata.md#message-attribute-data-types)。

会 适用于 Java 的 AWS SDK 自动计算消息正文和消息属性的校验和，并将它们与 Amazon SQS 返回的数据进行比较。有关更多信息，请参阅 *[AWS SDK for Java 2.x 开发人员指南](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/)*；有关其他编程语言，请参阅[计算 MD5 消息属性的消息摘要](sqs-message-metadata.md#sqs-attributes-md5-message-digest-calculation)。

------
#### [ String ]

此示例定义 `String` 属性，其名称为 `Name`，值为 `Jane`。

```
final Map<String, MessageAttributeValue> messageAttributes = new HashMap<>();
messageAttributes.put("Name", new MessageAttributeValue()
.withDataType("String")
.withStringValue("Jane"));
```

------
#### [ Number ]

此示例定义 `Number` 属性，其名称为 `AccurateWeight`，值为 `230.000000000000000001`。

```
final Map<String, MessageAttributeValue> messageAttributes = new HashMap<>();
messageAttributes.put("AccurateWeight", new MessageAttributeValue()
.withDataType("Number")
.withStringValue("230.000000000000000001"));
```

------
#### [ Binary ]

此示例定义 `Binary` 属性，其名称为 `ByteArray`，值为未初始化的 10 字节数组。

```
final Map<String, MessageAttributeValue> messageAttributes = new HashMap<>();
messageAttributes.put("ByteArray", new MessageAttributeValue()
.withDataType("Binary")
.withBinaryValue(ByteBuffer.wrap(new byte[10])));
```

------
#### [ String (custom) ]

此示例定义自定义属性 `String.EmployeeId`，其名称为 `EmployeeId`，值为 `ABC123456`。

```
final Map<String, MessageAttributeValue> messageAttributes = new HashMap<>();
messageAttributes.put("EmployeeId", new MessageAttributeValue()
.withDataType("String.EmployeeId")
.withStringValue("ABC123456"));
```

------
#### [ Number (custom) ]

此示例定义自定义属性 `Number.AccountId`，其名称为 `AccountId`，值为 `000123456`。

```
final Map<String, MessageAttributeValue> messageAttributes = new HashMap<>();
messageAttributes.put("AccountId", new MessageAttributeValue()
.withDataType("Number.AccountId")
.withStringValue("000123456"));
```

**注意**  
由于基本数据类型为 `Number`，`[ReceiveMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html)` 方法会返回 `123456`。

------
#### [ Binary (custom) ]

此示例定义自定义属性 `Binary.JPEG`，其名称为 `ApplicationIcon`，值为未初始化的 10 字节数组。

```
final Map<String, MessageAttributeValue> messageAttributes = new HashMap<>();
messageAttributes.put("ApplicationIcon", new MessageAttributeValue()
.withDataType("Binary.JPEG")
.withBinaryValue(ByteBuffer.wrap(new byte[10])));
```

------

## 发送带有属性的消息
<a name="sqs-java-send-attributes"></a>

此示例在发送消息之前将属性添加到 `SendMessageRequest` 中。

```
// Send a message with an attribute.
final SendMessageRequest sendMessageRequest = new SendMessageRequest();
sendMessageRequest.withMessageBody("This is my message text.");
sendMessageRequest.withQueueUrl(myQueueUrl);
sendMessageRequest.withMessageAttributes(messageAttributes);
sqs.sendMessage(sendMessageRequest);
```

**重要**  
如果您向 First-In-First-Out (FIFO) 队列发送消息，请确保在提供消息组 *ID 后*执行该`sendMessage`方法。  
如果您使用 `[SendMessageBatch](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessageBatch.html)` 方法而非 `[SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)`，则必须指定批处理中每条消息的消息属性。