Receiving a message

 


Messages are received using a QueueReceiver. This is created from a Session by using the createReceiver() method. This method takes a Queue parameter that defines from where the messages are received. See Sending a message for details of how to create a Queue object.

The sample program creates a receiver and reads back the test message with the following code:

QueueReceiver queueReceiver = session.createReceiver(ioQueue);
Message inMessage = queueReceiver.receive(1000);

The parameter in the receive call is a timeout in milliseconds. This parameter defines how long the method should wait if there is no message available immediately. You can omit this parameter, in which case, the call blocks indefinitely. If you do not want any delay, use the receiveNoWait() method.

The receive methods return a message of the appropriate type. For example, if a TextMessage is put on a queue, when the message is received the object that is returned is an instance of TextMessage.

To extract the content from the body of the message, it is necessary to cast from the generic Message class (which is the declared return type of the receive methods) to the more specific subclass, such as TextMessage. If the received message type is not known, you can use the instanceof operator to determine which type it is. It is good practice always to test the message class before casting, so that unexpected errors can be handled gracefully.

The following code illustrates the use of instanceof, and extraction of the content from a TextMessage:

if (inMessage instanceof TextMessage) {
  String replyString = ((TextMessage) inMessage).getText();
  .
  .
  .
} else {
  // Print error message if Message was not a TextMessage.
  System.out.println("Reply message was not a TextMessage");
}

 

Message selectors

JMS provides a mechanism to select a subset of the messages on a queue so that this subset is returned by a receive call. When creating a QueueReceiver, you can provide a string that contains an SQL (Structured Query Language) expression to determine which messages to retrieve. The selector can refer to fields in the JMS message header as well as fields in the message properties (these are effectively application-defined header fields).

The following example shows how to select for a user-defined property named myProp:

queueReceiver = session.createReceiver(ioQueue, "myProp = 'blue'");

Note:
The JMS specification does not permit the selector associated with a receiver to be changed. Once a receiver is created, the selector is fixed for the lifetime of that receiver. This means that, if you require different selectors, create new receivers.

 

Asynchronous delivery

An alternative to making calls to QueueReceiver.receive() is to register a method that is called automatically when a suitable message is available. The following fragment illustrates the mechanism:

import javax.jms.*;
 
public class MyClass implements MessageListener
{
  // The method that will be called by JMS when a message
  // is available.
  public void onMessage(Message message)
  {
    System.out.println("message is "+message);
 
    // application specific processing here
    .
    .
    .
  }
}
 
 .
 .
 .
  // In Main program (possibly of some other class)
  MyClass listener = new MyClass();
  queueReceiver.setMessageListener(listener);
 
  // main program can now continue with other application specific
  // behavior.

Note:
Use of asynchronous delivery with a QueueReceiver marks the entire Session as asynchronous. It is an error to make an explicit call to the receive methods of a QueueReceiver that is associated with a Session that is using asynchronous delivery.