Skip to content

Commit b6389a6

Browse files
committed
Jms request/reply operations
This commit updates JmsMessagingTemplate to support the MessageRequestReplyOperation interface that provides synchronous request/reply operations. As JmsMessagingTemplate delegates everything under the scenes to JmsTemplate, the latter has been updated as well to offer such lower level operation. Issue: SPR-12037
1 parent c89325b commit b6389a6

File tree

9 files changed

+557
-46
lines changed

9 files changed

+557
-46
lines changed

spring-jms/src/main/java/org/springframework/jms/core/JmsMessageOperations.java

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.messaging.MessagingException;
2525
import org.springframework.messaging.core.MessagePostProcessor;
2626
import org.springframework.messaging.core.MessageReceivingOperations;
27+
import org.springframework.messaging.core.MessageRequestReplyOperations;
2728
import org.springframework.messaging.core.MessageSendingOperations;
2829

2930
/**
@@ -35,8 +36,8 @@
3536
* @since 4.1
3637
* @see org.springframework.jms.core.JmsTemplate
3738
*/
38-
public interface JmsMessageOperations
39-
extends MessageSendingOperations<Destination>, MessageReceivingOperations<Destination> {
39+
public interface JmsMessageOperations extends MessageSendingOperations<Destination>,
40+
MessageReceivingOperations<Destination>, MessageRequestReplyOperations<Destination> {
4041

4142
/**
4243
* Send a message to the given destination.
@@ -109,4 +110,73 @@ void convertAndSend(String destinationName, Object payload, Map<String,
109110
*/
110111
<T> T receiveAndConvert(String destinationName, Class<T> targetClass) throws MessagingException;
111112

113+
/**
114+
* Send a request message and receive the reply from the given destination.
115+
* @param destinationName the name of the target destination
116+
* @param requestMessage the message to send
117+
* @return the reply, possibly {@code null} if the message could not be received,
118+
* for example due to a timeout
119+
*/
120+
Message<?> sendAndReceive(String destinationName, Message<?> requestMessage) throws MessagingException;
121+
122+
/**
123+
* Convert the given request Object to serialized form, possibly using a
124+
* {@link org.springframework.messaging.converter.MessageConverter}, send
125+
* it as a {@link Message} to the given destination, receive the reply and convert
126+
* its body of the specified target class.
127+
* @param destinationName the name of the target destination
128+
* @param request payload for the request message to send
129+
* @param targetClass the target type to convert the payload of the reply to
130+
* @return the payload of the reply message, possibly {@code null} if the message
131+
* could not be received, for example due to a timeout
132+
*/
133+
<T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass) throws MessagingException;
134+
135+
/**
136+
* Convert the given request Object to serialized form, possibly using a
137+
* {@link org.springframework.messaging.converter.MessageConverter}, send
138+
* it as a {@link Message} with the given headers, to the specified destination,
139+
* receive the reply and convert its body of the specified target class.
140+
* @param destinationName the name of the target destination
141+
* @param request payload for the request message to send
142+
* @param headers headers for the request message to send
143+
* @param targetClass the target type to convert the payload of the reply to
144+
* @return the payload of the reply message, possibly {@code null} if the message
145+
* could not be received, for example due to a timeout
146+
*/
147+
<T> T convertSendAndReceive(String destinationName, Object request, Map<String, Object> headers, Class<T> targetClass)
148+
throws MessagingException;
149+
150+
/**
151+
* Convert the given request Object to serialized form, possibly using a
152+
* {@link org.springframework.messaging.converter.MessageConverter},
153+
* apply the given post processor and send the resulting {@link Message} to the
154+
* given destination, receive the reply and convert its body of the given
155+
* target class.
156+
* @param destinationName the name of the target destination
157+
* @param request payload for the request message to send
158+
* @param targetClass the target type to convert the payload of the reply to
159+
* @param requestPostProcessor post process to apply to the request message
160+
* @return the payload of the reply message, possibly {@code null} if the message
161+
* could not be received, for example due to a timeout
162+
*/
163+
<T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass,
164+
MessagePostProcessor requestPostProcessor) throws MessagingException;
165+
166+
/**
167+
* Convert the given request Object to serialized form, possibly using a
168+
* {@link org.springframework.messaging.converter.MessageConverter},
169+
* wrap it as a message with the given headers, apply the given post processor
170+
* and send the resulting {@link Message} to the specified destination, receive
171+
* the reply and convert its body of the given target class.
172+
* @param destinationName the name of the target destination
173+
* @param request payload for the request message to send
174+
* @param targetClass the target type to convert the payload of the reply to
175+
* @param requestPostProcessor post process to apply to the request message
176+
* @return the payload of the reply message, possibly {@code null} if the message
177+
* could not be received, for example due to a timeout
178+
*/
179+
<T> T convertSendAndReceive(String destinationName, Object request, Map<String, Object> headers,
180+
Class<T> targetClass, MessagePostProcessor requestPostProcessor) throws MessagingException;
181+
112182
}

spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import org.springframework.jms.support.converter.SimpleMessageConverter;
2929
import org.springframework.messaging.Message;
3030
import org.springframework.messaging.MessagingException;
31-
import org.springframework.messaging.core.AbstractMessageReceivingTemplate;
31+
import org.springframework.messaging.core.AbstractMessagingTemplate;
3232
import org.springframework.messaging.core.MessagePostProcessor;
3333
import org.springframework.util.Assert;
3434

@@ -38,7 +38,7 @@
3838
* @author Stephane Nicoll
3939
* @since 4.1
4040
*/
41-
public class JmsMessagingTemplate extends AbstractMessageReceivingTemplate<Destination>
41+
public class JmsMessagingTemplate extends AbstractMessagingTemplate<Destination>
4242
implements JmsMessageOperations, InitializingBean {
4343

4444
private JmsTemplate jmsTemplate;
@@ -206,13 +206,76 @@ public <T> T receiveAndConvert(String destinationName, Class<T> targetClass) thr
206206
}
207207
}
208208

209+
@Override
210+
public Message<?> sendAndReceive(Message<?> requestMessage) {
211+
Destination defaultDestination = getDefaultDestination();
212+
if (defaultDestination != null) {
213+
return sendAndReceive(defaultDestination, requestMessage);
214+
}
215+
else {
216+
return sendAndReceive(getRequiredDefaultDestinationName(), requestMessage);
217+
}
218+
}
219+
220+
@Override
221+
public Message<?> sendAndReceive(String destinationName, Message<?> requestMessage)
222+
throws MessagingException {
223+
return doSendAndReceive(destinationName, requestMessage);
224+
}
225+
226+
@Override
227+
public <T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass)
228+
throws MessagingException {
229+
return convertSendAndReceive(destinationName, request, null, targetClass);
230+
}
231+
232+
@Override
233+
public <T> T convertSendAndReceive(Object request, Class<T> targetClass) {
234+
return convertSendAndReceive(request, targetClass, null);
235+
}
236+
237+
@Override
238+
public <T> T convertSendAndReceive(String destinationName, Object request,
239+
Map<String, Object> headers, Class<T> targetClass) throws MessagingException {
240+
241+
return convertSendAndReceive(destinationName, request, headers, targetClass, null);
242+
}
243+
244+
@Override
245+
public <T> T convertSendAndReceive(Object request, Class<T> targetClass, MessagePostProcessor postProcessor) {
246+
Destination defaultDestination = getDefaultDestination();
247+
if (defaultDestination != null) {
248+
return convertSendAndReceive(defaultDestination, request, targetClass, postProcessor);
249+
}
250+
else {
251+
return convertSendAndReceive(getRequiredDefaultDestinationName(), request, targetClass, postProcessor);
252+
}
253+
}
254+
255+
@Override
256+
public <T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass,
257+
MessagePostProcessor requestPostProcessor) throws MessagingException {
258+
259+
return convertSendAndReceive(destinationName, request, null, targetClass, requestPostProcessor);
260+
}
261+
262+
@SuppressWarnings("unchecked")
263+
@Override
264+
public <T> T convertSendAndReceive(String destinationName, Object request, Map<String, Object> headers,
265+
Class<T> targetClass, MessagePostProcessor postProcessor) {
266+
267+
Message<?> requestMessage = doConvert(request, headers, postProcessor);
268+
Message<?> replyMessage = sendAndReceive(destinationName, requestMessage);
269+
return (replyMessage != null ? (T) getMessageConverter().fromMessage(replyMessage, targetClass) : null);
270+
}
271+
209272
@Override
210273
protected void doSend(Destination destination, Message<?> message) {
211-
this.jmsTemplate.send(destination, new MessagingMessageCreator(message, this.jmsMessageConverter));
274+
this.jmsTemplate.send(destination, createMessageCreator(message));
212275
}
213276

214277
protected void doSend(String destinationName, Message<?> message) {
215-
this.jmsTemplate.send(destinationName, new MessagingMessageCreator(message, this.jmsMessageConverter));
278+
this.jmsTemplate.send(destinationName, createMessageCreator(message));
216279
}
217280

218281
@Override
@@ -226,6 +289,23 @@ protected Message<?> doReceive(String destinationName) {
226289
return doConvert(jmsMessage);
227290
}
228291

292+
@Override
293+
protected Message<?> doSendAndReceive(Destination destination, Message<?> requestMessage) {
294+
javax.jms.Message jmsMessage = this.jmsTemplate
295+
.sendAndReceive(destination, createMessageCreator(requestMessage));
296+
return doConvert(jmsMessage);
297+
}
298+
299+
protected Message<?> doSendAndReceive(String destinationName, Message<?> requestMessage) {
300+
javax.jms.Message jmsMessage = this.jmsTemplate
301+
.sendAndReceive(destinationName, createMessageCreator(requestMessage));
302+
return doConvert(jmsMessage);
303+
}
304+
305+
private MessagingMessageCreator createMessageCreator(Message<?> message) {
306+
return new MessagingMessageCreator(message, this.jmsMessageConverter);
307+
}
308+
229309
protected String getRequiredDefaultDestinationName() {
230310
String name = getDefaultDestinationName();
231311
if (name == null) {

spring-jms/src/main/java/org/springframework/jms/core/JmsOperations.java

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@
3232
* {@code receive(..)} methods that mirror various JMS API methods.
3333
* See the JMS specification and javadocs for details on those methods.
3434
*
35+
* <p>Provides also basic request reply operation using a temporary
36+
* queue to collect the reply.
37+
*
3538
* @author Mark Pollack
3639
* @author Juergen Hoeller
40+
* @author Stephane Nicoll
3741
* @since 1.1
3842
* @see JmsTemplate
3943
* @see javax.jms.Destination
@@ -83,9 +87,9 @@ public interface JmsOperations {
8387
<T> T execute(String destinationName, ProducerCallback<T> action) throws JmsException;
8488

8589

86-
//-------------------------------------------------------------------------
90+
//---------------------------------------------------------------------------------------
8791
// Convenience methods for sending messages
88-
//-------------------------------------------------------------------------
92+
//---------------------------------------------------------------------------------------
8993

9094
/**
9195
* Send a message to the default destination.
@@ -115,9 +119,9 @@ public interface JmsOperations {
115119
void send(String destinationName, MessageCreator messageCreator) throws JmsException;
116120

117121

118-
//-------------------------------------------------------------------------
122+
//---------------------------------------------------------------------------------------
119123
// Convenience methods for sending auto-converted messages
120-
//-------------------------------------------------------------------------
124+
//---------------------------------------------------------------------------------------
121125

122126
/**
123127
* Send the given object to the default destination, converting the object
@@ -185,9 +189,9 @@ void convertAndSend(String destinationName, Object message, MessagePostProcessor
185189
throws JmsException;
186190

187191

188-
//-------------------------------------------------------------------------
192+
//---------------------------------------------------------------------------------------
189193
// Convenience methods for receiving messages
190-
//-------------------------------------------------------------------------
194+
//---------------------------------------------------------------------------------------
191195

192196
/**
193197
* Receive a message synchronously from the default destination, but only
@@ -264,9 +268,9 @@ void convertAndSend(String destinationName, Object message, MessagePostProcessor
264268
Message receiveSelected(String destinationName, String messageSelector) throws JmsException;
265269

266270

267-
//-------------------------------------------------------------------------
271+
//---------------------------------------------------------------------------------------
268272
// Convenience methods for receiving auto-converted messages
269-
//-------------------------------------------------------------------------
273+
//---------------------------------------------------------------------------------------
270274

271275
/**
272276
* Receive a message synchronously from the default destination, but only
@@ -349,9 +353,54 @@ void convertAndSend(String destinationName, Object message, MessagePostProcessor
349353
Object receiveSelectedAndConvert(String destinationName, String messageSelector) throws JmsException;
350354

351355

352-
//-------------------------------------------------------------------------
356+
//---------------------------------------------------------------------------------------
357+
// Convenience methods for sending messages to and receiving the reply from a destination
358+
//---------------------------------------------------------------------------------------
359+
360+
/**
361+
* Send a request message and receive the reply from a default destination. The
362+
* {@link MessageCreator} callback creates the message given a Session. A temporary
363+
* queue is created as part of this operation and is set in the {@code JMSReplyTO}
364+
* header of the message.
365+
* <p>This will only work with a default destination specified!
366+
* @param messageCreator callback to create a request message
367+
* @return the reply, possibly {@code null} if the message could not be received,
368+
* for example due to a timeout
369+
* @throws JmsException checked JMSException converted to unchecked
370+
*/
371+
Message sendAndReceive(MessageCreator messageCreator) throws JmsException;
372+
373+
/**
374+
* Send a message and receive the reply from the specified destination. The
375+
* {@link MessageCreator} callback creates the message given a Session. A temporary
376+
* queue is created as part of this operation and is set in the {@code JMSReplyTO}
377+
* header of the message.
378+
* @param destination the destination to send this message to
379+
* @param messageCreator callback to create a message
380+
* @return the reply, possibly {@code null} if the message could not be received,
381+
* for example due to a timeout
382+
* @throws JmsException checked JMSException converted to unchecked
383+
*/
384+
Message sendAndReceive(Destination destination, MessageCreator messageCreator) throws JmsException;
385+
386+
/**
387+
* Send a message and receive the reply from the specified destination. The
388+
* {@link MessageCreator} callback creates the message given a Session. A temporary
389+
* queue is created as part of this operation and is set in the {@code JMSReplyTO}
390+
* header of the message.
391+
* @param destinationName the name of the destination to send this message to
392+
* (to be resolved to an actual destination by a DestinationResolver)
393+
* @param messageCreator callback to create a message
394+
* @return the reply, possibly {@code null} if the message could not be received,
395+
* for example due to a timeout
396+
* @throws JmsException checked JMSException converted to unchecked
397+
*/
398+
Message sendAndReceive(String destinationName, MessageCreator messageCreator) throws JmsException;
399+
400+
401+
//---------------------------------------------------------------------------------------
353402
// Convenience methods for browsing messages
354-
//-------------------------------------------------------------------------
403+
//---------------------------------------------------------------------------------------
355404

356405
/**
357406
* Browse messages in the default JMS queue. The callback gives access to the JMS

0 commit comments

Comments
 (0)