Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring JMSListener - How should it handle empty payloads?

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?

like image 529
LumberSzquatch Avatar asked Aug 04 '16 16:08

LumberSzquatch


3 Answers

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.

like image 144
LumberSzquatch Avatar answered Oct 27 '22 15:10

LumberSzquatch


@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

like image 33
M. Dicon Avatar answered Oct 27 '22 15:10

M. Dicon


You can add a custom message converter to the listener container factory and do whatever you want with the incoming message.

like image 42
Gary Russell Avatar answered Oct 27 '22 14:10

Gary Russell