3.6 Messages
The ultimate purpose of a JMS application is to produce and to consume messages that can then be used by other software applications. JMS messages have a basic format that is simple but highly flexible, allowing you to create messages that match formats used by non-JMS applications on heterogeneous platforms.
A JMS message has three parts:
- A header
- Properties (optional)
- A body (optional)
For complete documentation of message headers, properties, and bodies, see the documentation of the Message interface in Chapter 25.
3.6.1 Message Headers
A JMS message header contains a number of predefined fields that contain values that both clients and providers use to identify and to route messages. (Table 3.1 lists the JMS message header fields and indicates how their values are set.) For example, every message has a unique identifier, represented in the header field JMSMessageID. The value of another header field, JMSDestination, represents the queue or the topic to which the message is sent. Other fields include a timestamp and a priority level.
Each header field has associated setter and getter methods, which are documented in the description of the Message interface. Some header fields are intended to be set by a client, but many are set automatically by the send or the publish method, which overrides any client-set values.
Table 3.1: How JMS Message Header Field Values Are Set
Header Field Set By
JMSDestination |
send or publish method |
JMSDeliveryMode |
send or publish method |
JMSExpiration |
send or publish method |
JMSPriority |
send or publish method |
JMSMessageID |
send or publish method |
JMSTimestamp |
send or publish method |
JMSCorrelationID |
Client |
JMSReplyTo |
Client |
JMSType |
Client |
JMSRedelivered |
JMS provider |
3.6.2 Message Properties
You can create and set properties for messages if you need values in addition to those provided by the header fields. You can use properties to provide compatibility with other messaging systems, or you can use them to create message selectors (see Section 3.5.2 on page 23). For an example of setting a property to be used as a message selector, see Section 8.1.2.3 on page 102.
The JMS API provides some predefined property names that a provider may support. The use of either predefined properties or user-defined properties is optional.
3.6.3 Message Bodies
The JMS API defines five message body formats, also called message types, which allow you to send and to receive data in many different forms and provide compatibility with existing messaging formats. Table 3.2 describes these message types.
Table 3.2: JMS Message Types
Message Type |
Body Contains |
TextMessage |
A java.lang.String object (for example, the contents of an Extensible Markup Language file). |
MapMessage |
A set of name/value pairs, with names as String objects and values as primitive types in the Java programming language. The entries can be accessed sequentially by enumerator or randomly by name. The order of the entries is undefined. |
BytesMessage |
A stream of uninterpreted bytes. This message type is for literally encoding a body to match an existing message format. |
StreamMessage |
A stream of primitive values in the Java programming language, filled and read sequentially. |
ObjectMessage |
A Serializable object in the Java programming language. |
Message |
Nothing. Composed of header fields and properties only. This message type is useful when a message body is not required. |
The JMS API provides methods for creating messages of each type and for filling in their contents. For example, to create and send a TextMessage to a queue, you might use the following statements:
TextMessage message = queueSession.createTextMessage(); message.setText(msg_text); // msg_text is a String queueSender.send(message);
At the consuming end, a message arrives as a generic Message object and must be cast to the appropriate message type. You can use one or more getter methods to extract the message contents. The following code fragment uses the getText method:
Message m = queueReceiver.receive(); if (m instanceof TextMessage) { TextMessage message = (TextMessage) m; System.out.println("Reading message: " + message.getText()); } else { // Handle error }