Point-to-Point Messaging Example

You are now in a position to start coding. For all the following code examples, you will need to import the javax.jms package. This contains all the classes for creating connections, sessions, queues, and topics.

To send a JMS message, a number of steps must first be performed to obtain a connection factory, establish a session, and create a QueueSender object. Although the example is in the point-to-point message domain, the same steps are required for publish/subscribe topics.

The following steps show how to create a queue used later to send a simple text message.

1.
Obtain the JNDI initial context.

Context context = new InitialContext();

2.
Contact the JMS provider, obtain a JMS connection from the appropriate ConnectionFactory, and create a connection for a queue. The following code uses a connection factory registered against the default JNDI name jms/QueueConnectionFactory.

QueueConnectionFactory queueFactory = (QueueConnectionFactory)context.lookup("jms
/QueueConnectionFactory");
QueueConnection queueConnection = queueFactory.createQueueConnection();

The createQueueConnection() method throws a JMSException if the JMS provider fails to create the queue connection due to some internal error.

3.
Establish a QueueSession for this connection. In this case, the QueueSession has transactions set to false (transactions are covered later) and AUTO ACKNOWLEDGE of receipt of messages. This will throw a JMSException if the QueueConnection object fails to create a session.

QueueSession queueSession = queueConnection.createQueueSession(false, Session
.AUTO_ACKNOWLEDGE);
							

Note

Although sent messages are not acknowledged, a session can be used to receive messages created by its own connection. This is why an Acknowledge mode must be specified on a session, even if the queue is only used to send messages.

4.
Obtain the queue destination using its JNDI name as defined using j2eeadmin or deploytool. The lookup() method can throw a NamingException if the name is not found.

queue = (Queue)context.lookup("jms/firstQueue");

5.
Finally, create a queue sender that will be used to send messages. This will throw a JMSException if the session fails to create a sender, and an InvalidDestinationException if an invalid queue is specified.

QueueSender queueSender = queueSession.createSender(queue);

Note how the connection factory hides all the implementation details of the connection from the client. It does the hard work of creating resources, handling authentication, and supporting concurrent use.

Now you have a queue that is ready to send messages. But before that, you need to know a little more about JMS messages.

JMS Messages

JMS messages consist of three parts:

  • A header— Used to identify messages, set priority and expiration, and so on and to route messages.

  • Properties— Used to add additional information in addition to the message header.

  • Message body— There are five message body forms defined in JMS—BytesMessage, MapMessage, ObjectMessage, StreamMessage, and TextMessage.

Note that only the header is a required component of a message; the other two parts, including the body, are optional.

Message Header Fields

The JMS message header contains a number of fields that are generated by the JMS provider when the message is sent. These include the following:

  • JMSMessageID A unique identifier

  • JMSDestination Represents the queue or topic to which the message is sent

  • JMSRedelivered Set when the message has been resent for some reason

The following three header fields are available for the client to set:

  • JMSType A string that can be used to identify the contents of a message

  • JMSCorrelationID Used to link one message with another, typically used to link responses to requests

  • JMSReplyTo Used to define where responses should be sent

Other header fields may be set by the client but can be overridden by the JMS provider with figures set by an administrator:

  • JMSDeliveryMode This can be either PERSISTENT or NON_PERSISTENT (the default is PERSISTENT).

  • JMSPriority Providers recognize priorities between 0 and 9, with 9 being the highest (default is 4). Note that there is no guarantee that higher priority messages will be delivered before lower priority ones.

  • JMSTimestamp This contains the time the message was sent to the JMS provider by the application. Note that this is not the time the message is actually transmitted by the JMS provider to the receivers.

  • JMSExpiration An expiration time

Each header field has associated setter and getter methods that are fully described on the JMS API documentation.

Message Properties

As you have seen, there is not a great deal of scope for clients to add information to JMS header fields, but additionally JMS messages can incorporate properties. These are name/value pairs defined by the client.

Property values can be boolean, byte, short, int, long, float, double, or String and are defined using the appropriate Message.setProperty method. For example:

message.setStringProperty ("Type", "Java");

sets the message object's property called "Type" to the string "Java". A corresponding getProperty method is used to retrieve a message's property by name. The getPropertyNames() can be used if the names are not known.

The prefix JMSX is used for JMS-defined properties. Inclusion of these JMSX properties are optional; refer to your JMS provider documentation to determine what properties are supported in your JMS implementation.

JMS Body Types

JMS supports five types of message body. Each is defined by its own message interface. Each type is only briefly described in Table 9.4. Refer to the JMS API for more information on the message body types.

Table 9.4. JMS Message Body Types
Message Body Type Message Contents
BytesMessage Un-interpreted byte stream.
MapMessage Name/value pairs
ObjectMessage Serializable Java object
StreamMessage Stream of Java primitives
TextMessage Java String

Creating a Message

For the example given here, the default header properties will be used. Also, to keep this example straightforward, a TextMessage body will be used (this is also the most common message body type). A TextMessage object extends the Message interface and is used to send a message containing a String object.

A text message body is created using the createTextMessage() method in the QueueSession object.

TextMessage message = queueSession.createTextMessage(String);

The content of the a text message is added with message.setText():

String msg = "some text";
message.setText(msg);

Having created a message, you are ready to send it.

Sending a Message

A message must be sent to a queue QueueSender object as follows:

queueSender.send(queue, message);
						

It's as simple as that.

Closing the Connection

Connections are relatively heavyweight JMS objects, and you should always release the resources explicitly rather than depending on the garbage collector. The sender, the session, and the connection should all be closed when no more messages need to be sent.

queueSender.close();
queueSession.close();
queueConnection.close();

With the J2EE RI implementation, prior to releasing the QueueSender object, you must send a empty message to indicate no more messages will be sent. To do this, add the following line before the QueueSender object is closed.

queueSender.send(queueSession.createMessage());

Note

This code may not be required in other JMS implementations.


Send JMS Text Message Example

The code for the entire point-to-point sender example is shown in Listing 9.1.

Listing 9.1. Complete Listing for Point-to-Point Queue Sender
 1: import javax.naming.*;
 2: import javax.jms.*;
 3:
 4: public class PTPSender {
 5:     private QueueConnection queueConnection;
 6:     private QueueSession queueSession;
 7:     private QueueSender queueSender;
 8:     private Queue queue;
 9:
10:     public static void main(String[] args) {
11:     try {
12:          PTPSender sender = new PTPSender();
13:
14:         System.out.println ("Sending message Hello World");
15:         sender.sendMessage("Hello World");
16:         sender.close();
17:      } catch(Exception ex) {
18:         System.err.println("Exception in PTPSender: " + ex);
19:     }
20: }
21:
22:     public PTPSender() throws JMSException, NamingException {
23:         Context context = new InitialContext();
24:         QueueConnectionFactory queueFactory = (QueueConnectionFactory)context.lookup
("jms/QueueConnectionFactory");
25:         queueConnection = queueFactory.createQueueConnection();
26:         queueSession = queueConnection.createQueueSession(false, Session
.AUTO_ACKNOWLEDGE);
27:         queue = (Queue)context.lookup("jms/firstQueue");
28:         queueSender = queueSession.createSender(queue);
29:     }
30:
31:     public void sendMessage(String msg) throws JMSException {
32:         TextMessage message = queueSession.createTextMessage();
33:         message.setText(msg);
34:         queueSender.send(message);
35:     }
36:
37:     public void close() throws JMSException {
38:          //Send a non-text control message indicating end of messages
39:         queueSender.send(queueSession.createMessage());
40:         queueSender.close();
41:         queueSession.close();
42:         queueConnection.close();
43:     }
44:}
						

To send messages to the queue, run this program from the command line. The next example program will retrieve messages from that same queue for display onscreen.

Consuming Messages

There are two ways of consuming queued messages with JMS.

  • Synchronously— An explicit call to the receive() method.

  • Asynchronously— By registering an object that implements the MessageListener interface. The JMS provider invokes the onMessage() method in this object each time there is a message queued at the destination.

Figure 9.7 is a UML sequence diagram showing the difference between synchronous and asynchronous message consumption.

Figure 9.7. Synchronous and asynchronous message consumption.


The following example will demonstrate how to receive a message from a queue using a synchronous call.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.12.157