spring-cloud-aws Spring creates message header att

2019-08-05 15:45发布

问题:

I'm using Spring Cloud AWS messaging to send/receive messages using SQS.

My code looks like this:

@SpringBootApplication
@Import(MessagingConfig.class)
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}


@Configuration
public class MessagingConfig {

    @Bean
    public QueueMessagingTemplate queueMessagingTemplate(AmazonSQS amazonSqs, ResourceIdResolver resourceIdResolver) {
        return new QueueMessagingTemplate(amazonSqs, resourceIdResolver);
    }

}

The sender code is like this (wired via a controller):

@Component
public class Sender {

    @Autowired
    private QueueMessagingTemplate queueMessagingTemplate;

    public void send(MyMessage message) {
        queueMessagingTemplate.convertAndSend("testQueue", message);
    }
}

I have an application.yaml file that defines the AWS parameters that seem to be correctly loaded. So, when I run this application, I get the following warning/error:

Message header with name 'id' and type 'java.util.UUID' cannot be sent as message attribute because it is not supported by SQS.

Is there something that I'm doing wrong here, or is there an issue with the way Spring creates messages for SQS?

回答1:

This appears to be only a warning and does not affect the sending and/or receiving of the message. When I tested this against a real SQS queue, I could both send and receive messages.

However, when using elasticMQ on my local box as a replacement for the real SQS, it was failing to process the message. It looks like an issue with that tool rather than Spring.



回答2:

How to answer the question this

The problem occurs because the constructor called MessageHeaders class

MessageHeaders class

MessageHeaders(Map<String, Object> headers) { } on line 39

And to not send the id header you need to call the constructor MessageHeaders class

MessageHeaders(Map<String, Object> headers, UUID id, Long timestamp){} on line 43

because this constructor has the condition does not create the id header automatically

to stop sending the header id you need to override the MessageHeader and NotificationMessagingTemplate classes

class MessageHeaders

public class MessageHeadersCustom extends MessageHeaders {
    public MessageHeadersCustom() {
        super(new HashMap<String, Object>(), ID_VALUE_NONE, null);
    }
}

class NotificationMessagingTemplate

public class NotificationMessagingTemplateCustom extends NotificationMessagingTemplate {

    public NotificationMessagingTemplateCustom(AmazonSNS amazonSns) {
        super(amazonSns);
    }

    @Override
    public void sendNotification(Object message, String subject) {

        MessageHeaders headersCustom = new MessageHeadersCustom();
        headersCustom.put(TopicMessageChannel.NOTIFICATION_SUBJECT_HEADER, subject);

        this.convertAndSend(getRequiredDefaultDestination(), message, headersCustom);
    }
}

And finally, your class that will make the call need to use your implementation

package com.stackoverflow.sample.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.aws.messaging.core.NotificationMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/whatever")
public class SampleController {

    @Autowired
    private NotificationMessagingTemplateCustom template;

    @RequestMapping(method = RequestMethod.GET)
        public String handleGet() {
            this.template.sendNotification("message", "subject");
            return "yay";
        }
    }
}