问题
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?
回答1:
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.
回答2:
You can add a custom message converter to the listener container factory and do whatever you want with the incoming message.
回答3:
@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
来源:https://stackoverflow.com/questions/38773221/spring-jmslistener-how-should-it-handle-empty-payloads