diff options
Diffstat (limited to 'spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java')
-rw-r--r-- | spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java | 106 |
1 files changed, 94 insertions, 12 deletions
diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java index 10ae1cf8..2f53f57e 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,8 +36,10 @@ import org.springframework.jms.support.converter.MessageConversionException; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessagingMessageConverter; import org.springframework.jms.support.converter.SimpleMessageConverter; +import org.springframework.jms.support.converter.SmartMessageConverter; import org.springframework.jms.support.destination.DestinationResolver; import org.springframework.jms.support.destination.DynamicDestinationResolver; +import org.springframework.messaging.MessageHeaders; import org.springframework.util.Assert; /** @@ -269,14 +271,17 @@ public abstract class AbstractAdaptableMessageListener * @see #setMessageConverter */ protected Message buildMessage(Session session, Object result) throws JMSException { - Object content = (result instanceof JmsResponse ? ((JmsResponse<?>) result).getResponse() : result); - if (content instanceof org.springframework.messaging.Message) { - return this.messagingMessageConverter.toMessage(content, session); - } + Object content = preProcessResponse(result instanceof JmsResponse + ? ((JmsResponse<?>) result).getResponse() : result); MessageConverter converter = getMessageConverter(); if (converter != null) { - return converter.toMessage(content, session); + if (content instanceof org.springframework.messaging.Message) { + return this.messagingMessageConverter.toMessage(content, session); + } + else { + return converter.toMessage(content, session); + } } if (!(content instanceof Message)) { @@ -287,6 +292,17 @@ public abstract class AbstractAdaptableMessageListener } /** + * Pre-process the given result before it is converted to a {@link Message}. + * @param result the result of the invocation + * @return the payload response to handle, either the {@code result} argument + * or any other object (for instance wrapping the result). + * @since 4.3 + */ + protected Object preProcessResponse(Object result) { + return result; + } + + /** * Post-process the given response message before it will be sent. * <p>The default implementation sets the response's correlation id * to the request message's correlation id, if any; otherwise to the @@ -402,11 +418,21 @@ public abstract class AbstractAdaptableMessageListener /** - * Delegates payload extraction to {@link #extractMessage(javax.jms.Message)} to - * enforce backward compatibility. + * A {@link MessagingMessageConverter} that lazily invoke payload extraction and + * delegate it to {@link #extractMessage(javax.jms.Message)} in order to enforce + * backward compatibility. */ private class MessagingMessageConverterAdapter extends MessagingMessageConverter { + @SuppressWarnings("unchecked") + @Override + public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException { + if (message == null) { + return null; + } + return new LazyResolutionMessage(message); + } + @Override protected Object extractPayload(Message message) throws JMSException { Object payload = extractMessage(message); @@ -425,13 +451,69 @@ public abstract class AbstractAdaptableMessageListener } @Override - protected Message createMessageForPayload(Object payload, Session session) throws JMSException { + protected Message createMessageForPayload(Object payload, Session session, Object conversionHint) + throws JMSException { MessageConverter converter = getMessageConverter(); - if (converter != null) { - return converter.toMessage(payload, session); + if (converter == null) { + throw new IllegalStateException("No message converter, cannot handle '" + payload + "'"); } - throw new IllegalStateException("No message converter - cannot handle [" + payload + "]"); + if (converter instanceof SmartMessageConverter) { + return ((SmartMessageConverter) converter).toMessage(payload, session, conversionHint); + + } + return converter.toMessage(payload, session); } + + protected class LazyResolutionMessage implements org.springframework.messaging.Message<Object> { + + private final javax.jms.Message message; + + private Object payload; + + private MessageHeaders headers; + + public LazyResolutionMessage(javax.jms.Message message) { + this.message = message; + } + + @Override + public Object getPayload() { + if (this.payload == null) { + try { + this.payload = unwrapPayload(); + } + catch (JMSException ex) { + throw new MessageConversionException( + "Failed to extract payload from [" + this.message + "]", ex); + } + } + // + return this.payload; + } + + /** + * Extract the payload of the current message. Since we deferred the resolution + * of the payload, a custom converter may still return a full message for it. In + * this case, its payload is returned. + * @return the payload of the message + */ + private Object unwrapPayload() throws JMSException { + Object payload = extractPayload(this.message); + if (payload instanceof org.springframework.messaging.Message) { + return ((org.springframework.messaging.Message) payload).getPayload(); + } + return payload; + } + + @Override + public MessageHeaders getHeaders() { + if (this.headers == null) { + this.headers = extractHeaders(this.message); + } + return this.headers; + } + } + } |