Amazon SQS消息属性

时间:2014-09-16 16:49:03

标签: java amazon-web-services message-queue amazon-sqs

我无法正确添加属性。我正在使用AWS 1.7 当我添加它们时,它们会显示在邮件正文中,而不是属性中。当我登录AWS控制台时,我可以看到这一点。

我使用以下代码添加消息属性:

                Message awsMessage = new Message();         

    Map<String, MessageAttributeValue> messageAttributes = 
new HashMap<String, MessageAttributeValue>();

                messageAttributes.put("email", new MessageAttributeValue()
                .withDataType("String")
                .withStringValue(email));
                messageAttributes.put("data", new MessageAttributeValue()
                .withDataType("String")
                .withStringValue(newFileName));
                messageAttributes.put("template", new MessageAttributeValue()
                .withDataType("String")
                .withStringValue(filename));

                awsMessage.setMessageAttributes(messageAttributes);

我尝试使用它来提取属性:

List<Message> messages = SQSUtilityClass.getMessagesFromQueue(QUEUE_URL);
    int size = messages.size();
    Map<String, String> attributes = new HashMap<String, String>();
    System.out.println("Size: "+size);
    for(int x =0;x<size;x++){
        Message message = messages.get(x);
        //System.out.println(message.getBody());
        attributes = message.getAttributes();
        for(String key: attributes.keySet()){
            System.out.println(key + " - "+ attributes.get(key));
        }
    }

但是,当我通过AWS控制台查看时,我的属性位于邮件正文中。

2 个答案:

答案 0 :(得分:0)

您可以使用以下库生成SQS。

  <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>amazon-sqs-java-messaging-lib</artifactId>
      <version>${aws-messaging-lib-version}</version>
      <type>jar</type>
  </dependency>

以下是要生成的示例代码。

    SendMessageRequest request = new SendMessageRequest();
    request.withMessageAttributes(mapMessageAttributes(messageAttributes));
    request.setMessageBody(message);
    request.setQueueUrl(queueUrl);
    sqsClient.sendMessage(request);

其中mapMessageAttributes(messageAttributes)返回Map,sqsClient是AmazonSQSClient的实例。

一旦将属性传递给SQS,我就可以通过将它们设置为Spring DefaultMessageListenerContainer来使用JMS库。

        SQSConnectionFactory connectionFactory =
                SQSConnectionFactory.builder()
                        .withRegion(AWSSQSUtils.getAWSRegion(region))
                        .withAWSCredentialsProvider(new DefaultAWSCredentialsProviderChain())
                        .withNumberOfMessagesToPrefetch(prefetchCount)
                        .withClientConfiguration((new ClientConfiguration())
                                .withMaxConnections(connectionsCount)
                                .withProxyHost(proxyHost)
                                .withProxyPort(proxyPort))
                        .build();

        LOG.info("Connection factory initialized..");

        // Create the connection.
        SQSConnection connection = connectionFactory.createConnection();

        // Create the transacted session with UNORDERED_ACKNOWLEDGE mode.
        Session session = connection.createSession(false, SQSSession.UNORDERED_ACKNOWLEDGE);
        Queue immediateQueue = session.createQueue(safInputQueueImmediate);
        Queue normalQueue = session.createQueue(safInputQueueNormal);

        LOG.info("Connection established and session created..");

        //Create listeners
        immediateListnerContainer = new
                DefaultMessageListenerContainer();
        immediateListnerContainer.setConnectionFactory(connectionFactory);
        immediateListnerContainer.setMaxConcurrentConsumers(consumerConcurrency);
        immediateListnerContainer.setSessionAcknowledgeMode(SQSSession.UNORDERED_ACKNOWLEDGE);
        immediateListnerContainer.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER);
        immediateListnerContainer.setDestination(immediateQueue);
        immediateListnerContainer.setMessageListener(
                new StoreAndForwardListener(jobService, persistentMessagingDao));
        immediateListnerContainer.setMaxMessagesPerTask(maxMessagesPerTask);
        immediateListnerContainer.afterPropertiesSet();
        immediateListnerContainer.start();

我正在使用编程方法与声明式方法,因为SQS支持无序的aknowledge,Spring JMS尚不支持。

在MessageListener的onMessage方法中,您将获得一个javax.jms.Message对象,该对象可用于获取所有消息属性,如下所示。

Enumeration<String> headers = message.getPropertyNames();
while(headers.hasMoreElements()){
   attributeName = headers.nextElement();
   print(message.getStringProperty(attributeName))
}

希望有所帮助。

我确实在AWS上打开了一张故障单,其中一些属性在传输过程中被丢弃。即我设置M个属性,只有M-1或M-2属性才能进入SQS。一旦我有更新,我会在这里添加它。

答案 1 :(得分:0)

首先。您需要指定要随消息一起接收的属性。以下代码将接收属性emaildatatemplate(如您的示例):

final AmazonSQS sqs = // your code to get SQS instance
final String queue = // queue url
final List<Message> messages = sqs.receiveMessage(
    new ReceiveMessageRequest(queue)
        .withMessageAttributeNames("email", "data", "template")
).getMessages();

第二。您应该使用message.getMessageAttributes()而不是message.getAttributes()

final String email =
    message.getMessageAttributes().get("email").getStringValue()