3.5 Message Consumers
A message consumer is an object created by a session and is used for receiving messages sent to a destination. A message consumer allows a JMS client to register interest in a destination with a JMS provider. The JMS provider manages the delivery of messages from a destination to the registered consumers of the destination.
The PTP form of message consumer implements the QueueReceiver interface. The pub/sub form implements the TopicSubscriber interface.
For example, you use a QueueSession to create a receiver for the queue myQueue, and you use a TopicSession to create a subscriber for the topic myTopic:
QueueReceiver queueReceiver = queueSession.createReceiver(myQueue);
TopicSubscriber topicSubscriber = topicSession.createSubscriber(myTopic);
You use the TopicSession.createDurableSubscriber method to create a durable topic subscriber. For details, see Section 5.2.1 on page 61.
Once you have created a message consumer, it becomes active, and you can use it to receive messages. You can use the close method for a QueueReceiver or a TopicSubscriber to make the message consumer inactive. Message delivery does not begin until you start the connection you created by calling the start method (see Section 3.2 on page 18).
With either a QueueReceiver or a TopicSubscriber, you use the receive method to consume a message synchronously. You can use this method at any time after you call the start method:
queueConnection.start(); Message m = queueReceiver.receive();
topicConnection.start(); Message m = topicSubscriber.receive(1000); // time out after a second
To consume a message asynchronously, you use a message listener, described in Section 3.5.1 on page 22.
3.5.1 Message Listeners
A message listener is an object that acts as an asynchronous event handler for messages. This object implements the MessageListener interface, which contains one method, onMessage. In the onMessage method, you define the actions to be taken when a message arrives.
You register the message listener with a specific QueueReceiver or TopicSubscriber by using the setMessageListener method. For example, if you define a class named TopicListener that implements the MessageListener interface, you can register the message listener as follows:
TopicListener topicListener = new TopicListener(); topicSubscriber.setMessageListener(topicListener);
After you register the message listener, you call the start method on the QueueConnection or the TopicConnection to begin message delivery. (If you call start before you register the message listener, you are likely to miss messages.)
Once message delivery begins, the message consumer automatically calls the message listener's onMessage method whenever a message is delivered. The onMessage method takes one argument of type Message, which the method can cast to any of the other message types (see Section 3.6.3 on page 25).
A message listener is not specific to a particular destination type. The same listener can obtain messages from either a queue or a topic, depending on whether the listener is set by a QueueReceiver or a TopicSubscriber object. A message listener does, however, usually expect a specific message type and format. Moreover, if it needs to reply to messages, a message listener must either assume a particular destination type or obtain the destination type of the message and create a producer for that destination type.
Your onMessage method should handle all exceptions. It must not throw checked exceptions, and throwing a RuntimeException, though possible, is considered a programming error.
The session used to create the message consumer serializes the execution of all message listeners registered with the session. At any time, only one of the session's message listeners is running.
In the J2EE 1.3 platform, a message-driven bean is a special kind of message listener. For details, see Section 6.2 on page 69.
3.5.2 Message Selectors
If your messaging application needs to filter the messages it receives, you can use a JMS API message selector, which allows a message consumer to specify the messages it is interested in. Message selectors assign the work of filtering messages to the JMS provider rather than to the application. For an example of the use of a message selector, see Chapter 8.
A message selector is a String that contains an expression. The syntax of the expression is based on a subset of the SQL92 conditional expression syntax. The createReceiver, createSubscriber, and createDurableSubscriber methods each have a form that allows you to specify a message selector as an argument when you create a message consumer.
The message consumer then receives only messages whose headers and properties match the selector. (See Section 3.6.1 on page 23 and Section 3.6.2 on page 24.) A message selector cannot select messages on the basis of the content of the message body.