Add MessageSendingOperations for JMS
This commit adds a JMS implementation of MessageSendingOperations, allowing to send JMS messages using Spring's standard Messaging abstraction. MessagingMessageConverter is a standard JMS's MessageConverter that can convert Spring's Message to JMS message and vice versa. Existing infrastructure has been updated to use this implementation. Issue: SPR-11772
This commit is contained in:
parent
82336c320d
commit
7469159bf1
|
@ -32,6 +32,7 @@ import org.springframework.jms.support.JmsUtils;
|
|||
import org.springframework.jms.support.converter.JmsHeaderMapper;
|
||||
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.SimpleJmsHeaderMapper;
|
||||
import org.springframework.jms.support.converter.SimpleMessageConverter;
|
||||
import org.springframework.jms.support.destination.DestinationResolver;
|
||||
|
@ -60,7 +61,7 @@ public abstract class AbstractAdaptableMessageListener
|
|||
|
||||
private MessageConverter messageConverter;
|
||||
|
||||
private JmsHeaderMapper headerMapper = new SimpleJmsHeaderMapper();
|
||||
private MessagingMessageConverterAdapter messagingMessageConverter = new MessagingMessageConverterAdapter();
|
||||
|
||||
|
||||
/**
|
||||
|
@ -152,6 +153,10 @@ public abstract class AbstractAdaptableMessageListener
|
|||
return this.messageConverter;
|
||||
}
|
||||
|
||||
protected MessageConverter getMessagingMessageConverter() {
|
||||
return this.messagingMessageConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link JmsHeaderMapper} implementation to use to map the
|
||||
* standard JMS headers. By default {@link SimpleJmsHeaderMapper} is
|
||||
|
@ -160,15 +165,7 @@ public abstract class AbstractAdaptableMessageListener
|
|||
*/
|
||||
public void setHeaderMapper(JmsHeaderMapper headerMapper) {
|
||||
Assert.notNull(headerMapper, "HeaderMapper must not be null");
|
||||
this.headerMapper = headerMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link JmsHeaderMapper} that converts headers from
|
||||
* and to the messaging abstraction.
|
||||
*/
|
||||
protected JmsHeaderMapper getHeaderMapper() {
|
||||
return headerMapper;
|
||||
this.messagingMessageConverter.setHeaderMapper(headerMapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -284,10 +281,7 @@ public abstract class AbstractAdaptableMessageListener
|
|||
MessageConverter converter = getMessageConverter();
|
||||
if (converter != null) {
|
||||
if (result instanceof org.springframework.messaging.Message) {
|
||||
org.springframework.messaging.Message<?> message = (org.springframework.messaging.Message<?>) result;
|
||||
Message reply = converter.toMessage(message.getPayload(), session);
|
||||
getHeaderMapper().fromHeaders(message.getHeaders(), reply);
|
||||
return reply;
|
||||
return messagingMessageConverter.toMessage(result, session);
|
||||
}
|
||||
else {
|
||||
return converter.toMessage(result, session);
|
||||
|
@ -404,6 +398,18 @@ public abstract class AbstractAdaptableMessageListener
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delegates payload extraction to {@link #extractMessage(javax.jms.Message)} to
|
||||
* enforce backward compatibility.
|
||||
*/
|
||||
private class MessagingMessageConverterAdapter extends MessagingMessageConverter {
|
||||
|
||||
@Override
|
||||
protected Object extractPayload(Message message) throws JMSException {
|
||||
return extractMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal class combining a destination name
|
||||
* and its target destination type (queue or topic).
|
||||
|
|
|
@ -16,16 +16,14 @@
|
|||
|
||||
package org.springframework.jms.listener.adapter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.springframework.jms.support.converter.JmsHeaderMapper;
|
||||
import org.springframework.jms.support.converter.MessageConversionException;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.handler.invocation.InvocableHandlerMethod;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
* A {@link javax.jms.MessageListener} adapter that invokes a configurable
|
||||
|
@ -75,12 +73,12 @@ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageLis
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Message<?> toMessagingMessage(javax.jms.Message jmsMessage) {
|
||||
Map<String, Object> mappedHeaders = getHeaderMapper().toHeaders(jmsMessage);
|
||||
Object convertedObject = extractMessage(jmsMessage);
|
||||
MessageBuilder<Object> builder = (convertedObject instanceof org.springframework.messaging.Message) ?
|
||||
MessageBuilder.fromMessage((org.springframework.messaging.Message<Object>) convertedObject) :
|
||||
MessageBuilder.withPayload(convertedObject);
|
||||
return builder.copyHeadersIfAbsent(mappedHeaders).build();
|
||||
try {
|
||||
return (Message<?>) getMessagingMessageConverter().fromMessage(jmsMessage);
|
||||
}
|
||||
catch (JMSException e) {
|
||||
throw new MessageConversionException("Could not unmarshal message", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jms.messaging;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.jms.Destination;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.core.MessagePostProcessor;
|
||||
import org.springframework.messaging.core.MessageSendingOperations;
|
||||
|
||||
/**
|
||||
* A specialization of {@link MessageSendingOperations} for JMS related
|
||||
* operations that allows to specify a destination name rather than the
|
||||
* actual {@link javax.jms.Destination}
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
* @see org.springframework.jms.core.JmsTemplate
|
||||
*/
|
||||
public interface JmsMessageSendingOperations extends MessageSendingOperations<Destination> {
|
||||
|
||||
/**
|
||||
* Send a message to the given destination.
|
||||
* @param destinationName the name of the target destination
|
||||
* @param message the message to send
|
||||
*/
|
||||
void send(String destinationName, Message<?> message) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message and send it to the given destination.
|
||||
* @param destinationName the name of the target destination
|
||||
* @param payload the Object to use as payload
|
||||
*/
|
||||
void convertAndSend(String destinationName, Object payload) throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message with the given headers and send it to
|
||||
* the given destination.
|
||||
* @param destinationName the name of the target destination
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers headers for the message to send
|
||||
*/
|
||||
void convertAndSend(String destinationName, Object payload, Map<String, Object> headers)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message, apply the given post processor, and send
|
||||
* the resulting message to the given destination.
|
||||
* @param destinationName the name of the target destination
|
||||
* @param payload the Object to use as payload
|
||||
* @param postProcessor the post processor to apply to the message
|
||||
*/
|
||||
void convertAndSend(String destinationName, Object payload, MessagePostProcessor postProcessor)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message with the given headers, apply the given post processor,
|
||||
* and send the resulting message to the given destination.
|
||||
* @param destinationName the name of the target destination
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers headers for the message to send
|
||||
* @param postProcessor the post processor to apply to the message
|
||||
*/
|
||||
void convertAndSend(String destinationName, Object payload, Map<String,
|
||||
Object> headers, MessagePostProcessor postProcessor) throws MessagingException;
|
||||
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jms.messaging;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.jms.core.MessageCreator;
|
||||
import org.springframework.jms.support.converter.MessageConverter;
|
||||
import org.springframework.jms.support.converter.MessagingMessageConverter;
|
||||
import org.springframework.jms.support.converter.SimpleJmsHeaderMapper;
|
||||
import org.springframework.jms.support.converter.SimpleMessageConverter;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.core.AbstractMessageSendingTemplate;
|
||||
import org.springframework.messaging.core.MessagePostProcessor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An implementation of {@link JmsMessageSendingOperations}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
*/
|
||||
public class JmsMessagingTemplate
|
||||
extends AbstractMessageSendingTemplate<Destination>
|
||||
implements JmsMessageSendingOperations, InitializingBean {
|
||||
|
||||
private JmsTemplate jmsTemplate;
|
||||
|
||||
private MessageConverter jmsMessageConverter = new MessagingMessageConverter(
|
||||
new SimpleMessageConverter(), new SimpleJmsHeaderMapper());
|
||||
|
||||
private String defaultDestinationName;
|
||||
|
||||
public JmsMessagingTemplate() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with the {@link JmsTemplate} to use.
|
||||
*/
|
||||
public JmsMessagingTemplate(JmsTemplate jmsTemplate) {
|
||||
Assert.notNull("JmsTemplate must not be null");
|
||||
this.jmsTemplate = jmsTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link JmsTemplate} to use.
|
||||
*/
|
||||
public void setJmsTemplate(JmsTemplate jmsTemplate) {
|
||||
this.jmsTemplate = jmsTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link MessageConverter} to use to convert a {@link Message} from
|
||||
* the messaging to and from a {@link javax.jms.Message}. By default, a
|
||||
* {@link MessagingMessageConverter} is defined using a {@link SimpleMessageConverter}
|
||||
* to convert the payload of the message.
|
||||
* <p>Consider configuring a {@link MessagingMessageConverter} with a different
|
||||
* {@link MessagingMessageConverter#setPayloadConverter(MessageConverter) payload converter}
|
||||
* for more advanced scenario.
|
||||
*
|
||||
* @see org.springframework.jms.support.converter.MessagingMessageConverter
|
||||
*/
|
||||
public void setJmsMessageConverter(MessageConverter jmsMessageConverter) {
|
||||
this.jmsMessageConverter = jmsMessageConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the default destination name to use in send methods that don't have
|
||||
* a destination argument. If a default destination is not configured, send methods
|
||||
* without a destination argument will raise an exception if invoked.
|
||||
* @see #setDefaultDestination(Object)
|
||||
*/
|
||||
public void setDefaultDestinationName(String defaultDestinationName) {
|
||||
this.defaultDestinationName = defaultDestinationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured default destination name.
|
||||
*/
|
||||
public String getDefaultDestinationName() {
|
||||
return this.defaultDestinationName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.notNull(this.jmsTemplate, "Property 'jmsTemplate' is required");
|
||||
Assert.notNull(this.jmsMessageConverter, "Property 'jmsMessageConverter' is required");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void send(Message<?> message) {
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
send(defaultDestination, message);
|
||||
}
|
||||
else {
|
||||
send(getRequiredDefaultDestinationName(), message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(Object payload) throws MessagingException {
|
||||
convertAndSend(payload, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(Object payload, MessagePostProcessor postProcessor) throws MessagingException {
|
||||
Destination defaultDestination = getDefaultDestination();
|
||||
if (defaultDestination != null) {
|
||||
convertAndSend(defaultDestination, payload, postProcessor);
|
||||
}
|
||||
else {
|
||||
convertAndSend(getRequiredDefaultDestinationName(), payload, postProcessor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String destinationName, Message<?> message) throws MessagingException {
|
||||
doSend(destinationName, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(String destinationName, Object payload) throws MessagingException {
|
||||
convertAndSend(destinationName, payload, (Map<String, Object>) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(String destinationName, Object payload, Map<String, Object> headers)
|
||||
throws MessagingException {
|
||||
convertAndSend(destinationName, payload, headers, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(String destinationName, Object payload, MessagePostProcessor postProcessor)
|
||||
throws MessagingException {
|
||||
convertAndSend(destinationName, payload, null, postProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertAndSend(String destinationName, Object payload, Map<String, Object> headers,
|
||||
MessagePostProcessor postProcessor) throws MessagingException {
|
||||
Message<?> message = doConvert(payload, headers, postProcessor);
|
||||
send(destinationName, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doSend(Destination destination, Message<?> message) {
|
||||
jmsTemplate.send(destination, new MessagingMessageCreator(message, this.jmsMessageConverter));
|
||||
}
|
||||
|
||||
protected void doSend(String destinationName, Message<?> message) {
|
||||
jmsTemplate.send(destinationName, new MessagingMessageCreator(message, this.jmsMessageConverter));
|
||||
}
|
||||
|
||||
protected String getRequiredDefaultDestinationName() {
|
||||
String name = getDefaultDestinationName();
|
||||
if (name == null) {
|
||||
throw new IllegalStateException(
|
||||
"No 'defaultDestination' or 'defaultDestinationName' specified. " +
|
||||
"Check configuration of JmsMessagingTemplate."
|
||||
);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
private static class MessagingMessageCreator implements MessageCreator {
|
||||
|
||||
private final Message<?> message;
|
||||
|
||||
private final MessageConverter messageConverter;
|
||||
|
||||
private MessagingMessageCreator(Message<?> message, MessageConverter messageConverter) {
|
||||
this.message = message;
|
||||
this.messageConverter = messageConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.jms.Message createMessage(Session session) throws JMSException {
|
||||
return messageConverter.toMessage(message, session);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JMS integration for Spring's messaging module.
|
||||
*/
|
||||
package org.springframework.jms.messaging;
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jms.support.converter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Convert a {@link Message} from the messaging abstraction to
|
||||
* and from a {@link javax.jms.Message} using an underlying
|
||||
* {@link MessageConverter} for the payload and a {@link JmsHeaderMapper}
|
||||
* to map the JMS headers to and from standard message headers.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
*/
|
||||
public class MessagingMessageConverter implements MessageConverter, InitializingBean {
|
||||
|
||||
private MessageConverter payloadConverter;
|
||||
|
||||
private JmsHeaderMapper headerMapper;
|
||||
|
||||
/**
|
||||
* Create an instance with a default payload converter.
|
||||
* @see org.springframework.jms.support.converter.SimpleMessageConverter
|
||||
* @see org.springframework.jms.support.converter.SimpleJmsHeaderMapper
|
||||
*/
|
||||
public MessagingMessageConverter() {
|
||||
this(new SimpleMessageConverter(), new SimpleJmsHeaderMapper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with the specified payload converter and
|
||||
* header mapper.
|
||||
*/
|
||||
public MessagingMessageConverter(MessageConverter payloadConverter, JmsHeaderMapper headerMapper) {
|
||||
Assert.notNull(payloadConverter, "PayloadConverter must not be null");
|
||||
Assert.notNull(headerMapper, "HeaderMapper must not be null");
|
||||
this.payloadConverter = payloadConverter;
|
||||
this.headerMapper = headerMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link MessageConverter} to use to convert the payload.
|
||||
*/
|
||||
public void setPayloadConverter(MessageConverter payloadConverter) {
|
||||
this.payloadConverter = payloadConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link JmsHeaderMapper} to use to map JMS headers to and from
|
||||
* standard message headers.
|
||||
*/
|
||||
public void setHeaderMapper(JmsHeaderMapper headerMapper) {
|
||||
this.headerMapper = headerMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.notNull(this.payloadConverter, "Property 'payloadConverter' is required");
|
||||
Assert.notNull(this.headerMapper, "Property 'headerMapper' is required");
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.jms.Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
|
||||
if (!(object instanceof Message)) {
|
||||
throw new IllegalArgumentException("Could not convert [" + object + "] only ["
|
||||
+ Message.class.getName() + "] is handled by this converter");
|
||||
}
|
||||
|
||||
Message<?> input = (Message<?>) object;
|
||||
javax.jms.Message reply = this.payloadConverter.toMessage(input.getPayload(), session);
|
||||
this.headerMapper.fromHeaders(input.getHeaders(), reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException {
|
||||
Map<String, Object> mappedHeaders = this.headerMapper.toHeaders(message);
|
||||
Object convertedObject = extractPayload(message);
|
||||
MessageBuilder<Object> builder = (convertedObject instanceof org.springframework.messaging.Message) ?
|
||||
MessageBuilder.fromMessage((org.springframework.messaging.Message<Object>) convertedObject) :
|
||||
MessageBuilder.withPayload(convertedObject);
|
||||
return builder.copyHeadersIfAbsent(mappedHeaders).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the payload of the specified {@link javax.jms.Message}
|
||||
*/
|
||||
protected Object extractPayload(javax.jms.Message message) throws JMSException {
|
||||
return this.payloadConverter.fromMessage(message);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jms.messaging;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.BDDMockito.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.jms.StubTextMessage;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.jms.core.MessageCreator;
|
||||
import org.springframework.jms.support.converter.MessageConversionException;
|
||||
import org.springframework.jms.support.converter.SimpleMessageConverter;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class JmsMessagingTemplateTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<MessageCreator> messageCreator;
|
||||
|
||||
@Mock
|
||||
private JmsTemplate jmsTemplate;
|
||||
|
||||
private JmsMessagingTemplate messagingTemplate;
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
messagingTemplate = new JmsMessagingTemplate(jmsTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void send() {
|
||||
Destination destination = new Destination() {};
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
messagingTemplate.send(destination, message);
|
||||
verify(jmsTemplate).send(eq(destination), messageCreator.capture());
|
||||
assertTextMessage(messageCreator.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendName() {
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
messagingTemplate.send("myQueue", message);
|
||||
verify(jmsTemplate).send(eq("myQueue"), messageCreator.capture());
|
||||
assertTextMessage(messageCreator.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendDefaultDestination() {
|
||||
Destination destination = new Destination() {};
|
||||
messagingTemplate.setDefaultDestination(destination);
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
messagingTemplate.send(message);
|
||||
verify(jmsTemplate).send(eq(destination), messageCreator.capture());
|
||||
assertTextMessage(messageCreator.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendDefaultDestinationName() {
|
||||
messagingTemplate.setDefaultDestinationName("myQueue");
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
messagingTemplate.send(message);
|
||||
verify(jmsTemplate).send(eq("myQueue"), messageCreator.capture());
|
||||
assertTextMessage(messageCreator.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendNoDefaultSet() {
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
thrown.expect(IllegalStateException.class);
|
||||
messagingTemplate.send(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendPropertyInjection() {
|
||||
JmsMessagingTemplate t = new JmsMessagingTemplate();
|
||||
t.setJmsTemplate(jmsTemplate);
|
||||
t.setDefaultDestinationName("myQueue");
|
||||
t.afterPropertiesSet();
|
||||
Message<String> message = createTextMessage();
|
||||
|
||||
t.send(message);
|
||||
verify(jmsTemplate).send(eq("myQueue"), messageCreator.capture());
|
||||
assertTextMessage(messageCreator.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertAndSendPayload() throws JMSException {
|
||||
Destination destination = new Destination() {};
|
||||
|
||||
messagingTemplate.convertAndSend(destination, "my Payload");
|
||||
verify(jmsTemplate).send(eq(destination), messageCreator.capture());
|
||||
TextMessage textMessage = createTextMessage(messageCreator.getValue());
|
||||
assertEquals("my Payload", textMessage.getText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertAndSendPayloadName() throws JMSException {
|
||||
messagingTemplate.convertAndSend("myQueue", "my Payload");
|
||||
verify(jmsTemplate).send(eq("myQueue"), messageCreator.capture());
|
||||
TextMessage textMessage = createTextMessage(messageCreator.getValue());
|
||||
assertEquals("my Payload", textMessage.getText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertAndSendDefaultDestination() throws JMSException {
|
||||
Destination destination = new Destination() {};
|
||||
messagingTemplate.setDefaultDestination(destination);
|
||||
|
||||
messagingTemplate.convertAndSend("my Payload");
|
||||
verify(jmsTemplate).send(eq(destination), messageCreator.capture());
|
||||
TextMessage textMessage = createTextMessage(messageCreator.getValue());
|
||||
assertEquals("my Payload", textMessage.getText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertAndSendDefaultDestinationName() throws JMSException {
|
||||
messagingTemplate.setDefaultDestinationName("myQueue");
|
||||
|
||||
messagingTemplate.convertAndSend("my Payload");
|
||||
verify(jmsTemplate).send(eq("myQueue"), messageCreator.capture());
|
||||
TextMessage textMessage = createTextMessage(messageCreator.getValue());
|
||||
assertEquals("my Payload", textMessage.getText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertAndSendNoDefaultSet() throws JMSException {
|
||||
thrown.expect(IllegalStateException.class);
|
||||
messagingTemplate.convertAndSend("my Payload");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertAndSendCustomJmsMessageConverter() throws JMSException {
|
||||
messagingTemplate.setJmsMessageConverter(new SimpleMessageConverter() {
|
||||
@Override
|
||||
public javax.jms.Message toMessage(Object object, Session session)
|
||||
throws JMSException, MessageConversionException {
|
||||
throw new MessageConversionException("Test exception");
|
||||
}
|
||||
});
|
||||
|
||||
messagingTemplate.convertAndSend("myQueue", "msg to convert");
|
||||
verify(jmsTemplate).send(eq("myQueue"), messageCreator.capture());
|
||||
|
||||
thrown.expect(MessageConversionException.class);
|
||||
thrown.expectMessage("Test exception");
|
||||
messageCreator.getValue().createMessage(mock(Session.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertAndSendPayloadAndHeaders() throws JMSException {
|
||||
Destination destination = new Destination() {};
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
headers.put("foo", "bar");
|
||||
|
||||
messagingTemplate.convertAndSend(destination, "Hello", headers);
|
||||
verify(jmsTemplate).send(eq(destination), messageCreator.capture());
|
||||
assertTextMessage(messageCreator.getValue()); // see createTextMessage
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertAndSendPayloadAndHeadersName() throws JMSException {
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
headers.put("foo", "bar");
|
||||
|
||||
messagingTemplate.convertAndSend("myQueue", "Hello", headers);
|
||||
verify(jmsTemplate).send(eq("myQueue"), messageCreator.capture());
|
||||
assertTextMessage(messageCreator.getValue()); // see createTextMessage
|
||||
}
|
||||
|
||||
|
||||
private Message<String> createTextMessage() {
|
||||
return MessageBuilder
|
||||
.withPayload("Hello").setHeader("foo", "bar").build();
|
||||
}
|
||||
|
||||
private void assertTextMessage(MessageCreator messageCreator) {
|
||||
try {
|
||||
TextMessage jmsMessage = createTextMessage(messageCreator);
|
||||
assertEquals("Wrong body message", "Hello", jmsMessage.getText());
|
||||
assertEquals("Invalid foo property", "bar", jmsMessage.getStringProperty("foo"));
|
||||
}
|
||||
catch (JMSException e) {
|
||||
throw new IllegalStateException("Wrong text message", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected TextMessage createTextMessage(MessageCreator creator) throws JMSException {
|
||||
Session mock = mock(Session.class);
|
||||
given(mock.createTextMessage(any())).willAnswer(new Answer<TextMessage>() {
|
||||
@Override
|
||||
public TextMessage answer(InvocationOnMock invocation) throws Throwable {
|
||||
return new StubTextMessage((String) invocation.getArguments()[0]);
|
||||
}
|
||||
});
|
||||
javax.jms.Message message = creator.createMessage(mock);
|
||||
verify(mock).createTextMessage(any());
|
||||
return TextMessage.class.cast(message);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jms.support.converter;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.BDDMockito.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.ObjectMessage;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.jms.StubTextMessage;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class MessagingMessageConverterTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private final MessagingMessageConverter converter = new MessagingMessageConverter();
|
||||
|
||||
@Test
|
||||
public void onlyHandlesMessage() throws JMSException {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
converter.toMessage(new Object(), mock(Session.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleObject() throws Exception {
|
||||
Session session = mock(Session.class);
|
||||
Serializable payload = mock(Serializable.class);
|
||||
ObjectMessage jmsMessage = mock(ObjectMessage.class);
|
||||
given(session.createObjectMessage(payload)).willReturn(jmsMessage);
|
||||
|
||||
converter.toMessage(MessageBuilder.withPayload(payload).build(), session);
|
||||
verify(session).createObjectMessage(payload);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customPayloadConverter() throws JMSException {
|
||||
TextMessage jmsMsg = new StubTextMessage("1224");
|
||||
|
||||
converter.setPayloadConverter(new SimpleMessageConverter() {
|
||||
@Override
|
||||
public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException {
|
||||
TextMessage textMessage = (TextMessage) message;
|
||||
return Long.parseLong(textMessage.getText());
|
||||
}
|
||||
});
|
||||
|
||||
Message<?> msg = (Message<?>) converter.fromMessage(jmsMsg);
|
||||
assertEquals(1224L, msg.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void payloadIsAMessage() throws JMSException {
|
||||
final Message<String> message = MessageBuilder.withPayload("Test").setHeader("inside", true).build();
|
||||
converter.setPayloadConverter(new SimpleMessageConverter() {
|
||||
@Override
|
||||
public Object fromMessage(javax.jms.Message jmsMessage) throws JMSException, MessageConversionException {
|
||||
return message;
|
||||
}
|
||||
});
|
||||
Message<?> msg = (Message<?>) converter.fromMessage(new StubTextMessage());
|
||||
assertEquals(message.getPayload(), msg.getPayload());
|
||||
assertEquals(true, msg.getHeaders().get("inside"));
|
||||
}
|
||||
|
||||
}
|
|
@ -34,6 +34,7 @@ import org.springframework.util.Assert;
|
|||
*
|
||||
* @author Mark Fisher
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class AbstractMessageSendingTemplate<D> implements MessageSendingOperations<D> {
|
||||
|
@ -99,7 +100,7 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
|
|||
|
||||
@Override
|
||||
public void convertAndSend(Object payload) throws MessagingException {
|
||||
convertAndSend(getRequiredDefaultDestination(), payload);
|
||||
convertAndSend(payload, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -128,6 +129,20 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
|
|||
public void convertAndSend(D destination, Object payload, Map<String, Object> headers,
|
||||
MessagePostProcessor postProcessor) throws MessagingException {
|
||||
|
||||
Message<?> message = doConvert(payload, headers, postProcessor);
|
||||
send(destination, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link MessageConverter}, wrap it as a message with the given
|
||||
* headers and apply the given post processor.
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers headers for the message to send
|
||||
* @param postProcessor the post processor to apply to the message
|
||||
* @return the converted message
|
||||
*/
|
||||
protected Message<?> doConvert(Object payload, Map<String, Object> headers, MessagePostProcessor postProcessor) {
|
||||
MessageHeaders messageHeaders = null;
|
||||
Map<String, Object> headersToUse = processHeadersToSend(headers);
|
||||
if (headersToUse != null) {
|
||||
|
@ -149,7 +164,7 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
|
|||
if (postProcessor != null) {
|
||||
message = postProcessor.postProcessMessage(message);
|
||||
}
|
||||
send(destination, message);
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
|
@ -66,7 +66,7 @@ public interface MessageSendingOperations<D> {
|
|||
* Convert the given Object to serialized form, possibly using a
|
||||
* {@link org.springframework.messaging.converter.MessageConverter},
|
||||
* wrap it as a message with the given headers and send it to
|
||||
* a default destination.
|
||||
* the given destination.
|
||||
* @param destination the target destination
|
||||
* @param payload the Object to use as payload
|
||||
* @param headers headers for the message to send
|
||||
|
|
|
@ -40428,6 +40428,10 @@ clear, the `JmsTemplate` is stateful, in that it maintains a reference to a
|
|||
`ConnectionFactory`, but this state is __not__ conversational state.
|
||||
====
|
||||
|
||||
As of Spring Framework 4.1, `JmsMessagingTemplate` is built on top of `JmsTemplate`
|
||||
and provides an integration with the messaging abstraction, i.e.
|
||||
`org.springframework.messaging.Message`. This allows you to create the message to
|
||||
send in generic manner.
|
||||
|
||||
|
||||
[[jms-connections]]
|
||||
|
|
Loading…
Reference in New Issue