I asked basically the same thing a few months ago with this post: How should a Spring JMS listener handle a message with an empty payload?, but all I got was a measly comment suggesting I "re-write my listener to do what I want". Valid statement, but unclear in my eyes as I'm still coming to grips with Spring-Boot. I've learned since then and want to re-ask this question more directly (as opposed to placing a bounty on the old one).
I set up an annotated bean class with @Configuration
and @EnableJms
and my container factory looks like:
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(mqConnectionFactory());
factory.setDestinationResolver(destinationResolver());
factory.setConcurrency("1");
factory.setErrorHandler(errorHandler());
factory.setSessionTransacted(true);
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
return factory;
}
And the listener looks like:
@JmsListener(id = "qID", destination = "qName")
public void processOrder(String message) {. . .}
As I understand it, once the annotated bean class gets ran through, the JMSListener
basically kicks off (unless I set autoStartup
to false), so I fail to understand where and when I have control over what or how the JmsListener
handles things. From my perspective it "just runs". So if a queue has "\n"
on it or just an empty string, the listener is going to throw an exception. Specifically org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class java.lang.String
. And this exception is thrown behind the scenes. I never get the chance to execute anything inside the listener
I looked into SimpleMessageConverter
but didn't seem to see anything that would allow me to say something like setIgnoreStringPattern()
. That obviously doesn't exist, but that's what I need. What am I missing? Is there a way to tell the JmsListener
to ignore certain strings?
I took M. Deinum's suggestion (as it seemed quick and clean) and simply made the parameter type javax.jms.Message
then converted the incoming message into a string. So my Listener now looks like
@JmsListener
public void processOrder(Message message) throws JMSException {
String convertedMessage = ((TextMessage) message).getText();
:
:
}
This may throw a JMSException, but I'm not too concerned with that as now when my implemented ErrorHandler
class is called, I'll now know why and can do something more specific to handle a failed conversion. This does exactly what I need it to.
Edit: And in response to Jonh K's suggestion, the listener did not like having byte[]
as a parameter. It basically wanted a converter to convert from byte array to string. Opted out of implementing my own custom converter.
@JmsListener(destination = "stompmessage")
public void receiveStomp(byte[] data, @Headers Map<Object, Object> allHeaders) {
System.out.println("Stomp message: "+ new String(data));
}
Version for spring in 2019-2020
You can add a custom message converter to the listener container factory and do whatever you want with the incoming message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With