JMS Request-Reply Example

This example shows you how to handle a request message and receive a reply. To get a reply message, the requesting client creates a temporary queue. Then it sends out the request message with JMSReplyTo set to the temporary queue. The request message is handled by a SimpleRequestServer, who is listening to the request queue for incoming requests. If a request message has arrived, it extracts the reply queue from the request message by JMSReplyTo header, and sends back a reply message. To let the client know to which request message a reply message is related, the server also set the JMSCorrelationID with the request message's JMSMessageID header to the reply message.

Of course, in a real world example you would re-use the session, producer, consumer and temporary queue and not create a new one for each message! Or better still use the correlation id, and just store the requests in a map, then you don't need a temporary queue at all

Request/Reply style messaging is supported through standard JMS message headers JMSReplyTo and JMSCorrelationID. This is often used in request-reply style communications between applications. Whenever a client sends a message that expects a response, it can use this mechanism to implement. please consult the JMS 1.1 specification for full details.

Example step-by-step

To run the example, simply type mvn verify from this directory

  1. We start the request server
  2.            SimpleRequestServer server = new SimpleRequestServer();
               server.start();
            
  3. We need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get it's properties from the client-jndi.properties file in the directory ../common/config
  4.            initialContext = getContext();
            
  5. We lookup the queue for sending the request message
  6.            Queue requestQueue = (Queue) initialContext.lookup("/queue/exampleQueue");
            
  7. We lookup for the Connection Factory
  8.            ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");
            
  9. We create a JMS Connection
  10.            connection = cf.createConnection();
            
  11. We start the connection
  12.            connection.start();
            
  13. We create a JMS Session
  14.            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            
  15. We create a JMS Message Producer to send request message
  16.            MessageProducer producer = session.createProducer(requestQueue);
            
  17. We create a temporary queue used to send reply message to and receive reply from
  18.            TemporaryQueue replyQueue = session.createTemporaryQueue();
            
  19. We create a consumer to receive reply message
  20.            MessageConsumer replyConsumer = session.createConsumer(replyQueue);
            
  21. We create a request Text Message
  22.            TextMessage requestMsg = session.createTextMessage("A request message");
            
  23. We set the ReplyTo header so that the request receiver knows where to send the reply.
  24.            requestMsg.setJMSReplyTo(replyQueue);
            
  25. We sent the request message
  26.            producer.send(requestMsg);
            
  27. We put the request message to the map. Later we use it to check out which request message a reply message is for. Here we use the MessageID as the correlation id (JMSCorrelationID). You don't have to use it though. You can use some arbitrary string for example.
  28.            requestMap.put(requestMsg.getJMSMessageID(), requestMsg);
            
  29. We receive the reply message
  30.            TextMessage replyMessageReceived = (TextMessage)replyConsumer.receive();
            
  31. We check out which request message is this reply message sent for. Here we just have one request message for illustrative purpose. In real world there may be many requests and many replies.
  32.            TextMessage matchedMessage = requestMap.get(replyMessageReceived.getJMSCorrelationID());
            
  33. We close the consumer and producer on the replyQueue
  34.            replyConsumer.close();
            
  35. We delete the temporary queue
  36.            replyQueue.delete();
            
  37. We shutdown the request server
  38.            server.shutdown();
            
  39. And finally, always remember to close your JMS connections and resources after use, in a finally block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects
  40.            finally
               {
                  if (initialContext != null)
                  {
                    initialContext.close();
                  }
                  if (connection != null)
                  {
                     connection.close();
                  }
               }
            
Request Messages are handled in SimpleRequestServer.onMessage(),
  1. Extract the ReplyTo destination
  2.            Destination replyDestination = request.getJMSReplyTo();
            
  3. Create the reply message
  4.            TextMessage replyMessage = session.createTextMessage("A reply message");
            
  5. Set the CorrelationID
  6.            replyMessage.setJMSCorrelationID(request.getJMSCorrelationID());
            
  7. Send out the reply message
  8.            replyProducer.send(replyMessage);