JMS(Java Message Service) Message Structure
1. Message Header
1.1. JMSDestination
The destination to which the message is being sent—for example, Queue or Topic. Its value is set by the provider after completion of the send and matches the destination associated with the MessageProducer. A getter method is defined to allow the receiving application to access the value of JMSDestination. However, although a setter method is provided, the value of JMSDestination is ignored during a send.
1.2. JMSDeliveryMode
JMSDeliveryMode is used to define the persistence of a message. A nonpersistent message is not logged to a persistent message store by the provider, implying that the message cannot be recovered in the event of a provider process failure. Persistent messages, on the other hand, are logged and are thus recoverable by the provider when it restarts. JMSDeliveryMode holds an integer value defined by the interface DeliveryMode. DeliveryMode contains two static integer values: NONPERSISTENT and PERSISTENT. The value of JMSDeliveryMode is set by the provider after completion of the send. It is based on the value specified by the sending method, which can be either DeliveryMode.NONPERSISTENT or DeliveryMode.PERSISTENT. The provider defaults to persistent delivery if no value is specified. As with JMSDestination, any value set by the setter method is ignored on send. A getter method provides access to the populated value.
1.3. JMSMessageID
JMSMessageID uniquely identifies a message. It is defined as a String and ignored if set when the message is sent. It is populated with a provider-assigned value on completion of the send. The provider-assigned identifier is prefixed with ID:.
1.4. JMSTimestamp
The JMSTimeStamp field is populated by the provider during the send; the value set is in the format of a normal Java millisecond time value.
1.5. JMSExpiration
JMSExpiration stores the expiration time of the message. This is calculated as the current time plus a specified timeToLive. The value of timeToLive is specified on the sending method in milliseconds, and the provider populates JMSExpiration (type Long) with the computed value in milliseconds on completion of the send. If a value for timeToLive is not specified or is specified as zero, JMSExpiration is set to zero, signifying that the message does not expire. Any value set for JMSExpiration is ignored on the send. Once a message has expired, the JMS client is unable to retrieve the message. Typically, the message is discarded by the provider at this point. JMSExpiration provides a convenient way to clean up messages that have a well-defined relevance period, such as a reply to a request that has arrived late.
1.6. JMSRedelivered
The JMSRedelivered field takes a Boolean value set by the provider to signify that the message has been previously delivered to the client. It is only relevant when consuming a message and serves to alert the client (if checked) that it has previously attempted processing of this message. Recall from our discussion of message consumers and "poison" messages in Chapter 1, "Enterprise Messaging," that JMSRedelivered can help address the issue of infinite repeated processing, which could occur if the message is being processed within a transaction and being redelivered because processing failed.
1.7. JMSPriority
JMS defines transmission priority levels 0 to 9, with 0 as the lowest priority and 9 as the highest. It additionally specifies that priorities 0 to 4 should be considered gradations of normal delivery and priorities 5 to 9 as gradations of expedited delivery. The provider populates JMSPriority (type int) on completion of the send based on the value specified by the sending method.
1.8. JMSReplyTo
JMSReplyTo is set by the client and takes as value a Destination object that specifies where replies to this message are to be sent. This implies that this field is set only if a reply is required. By default it is set to null.
1.9. JMSCorrelationID
The JMSCorrelationID field is typically used to link two messages together. For example, in order to link a given reply to a request, the JMS client could specify that the JMSCorrelationID of the incoming reply should match the JMSMessageID of the sent request. This requires the servicing client to set the JMSCorrelationID of the reply to the JMSMessageID of the request before sending the reply. Consequently, if used, this field is set by the JMS client.
JMS additionally allows for the case where the JMS client needs to use a specific value for linking messages; in this case an alternative string value can be set, but it should not be prefixed with ID:. If the JMS client is servicing a request from a non-JMS client and needs to assign a specific value for use with such clients, JMS defines a byte array optional type for JMSCorrelationID. However, providers are not required to implement support for this optional type.
1.10. JMSType
JMSType contains a message type identifier that is set by the client. Its purpose is to enable clients of providers who provide a message definition repository to associate with the contained message body a reference to its physical format definition in the provider's message repository.
2. Message Properties
Properties are used to add optional fields to the header. A property can be specified by the application, be one of the standard properties defined by JMS, or be provider-specific. When sending a message, properties can be set using associated setter methods. In the received message, properties are read-only, and any attempt to set the properties on a received message results in a MessageNotWriteableException. If it is desired to modify the properties of a received message—for instance, the application is performing a brokering function and needs to modify the attributes of the message before forwarding it to the next destination—then the clearProperties() method is called on the message object.
3. Message Body
3.1. TextMessage
TextMessage stores data as a String, a common representation of enterprise data.
3.2. MapMessage
MapMessage stores data as a set of key-value pairs. The key is defined as a string, and the value is typed—for example, Age:33, where Age is the key and 33 the integer value.
3.3. BytesMessage
BytesMessage stores data as a sequence of bytes, supports the most basic representation of data, and thus can contain varied payloads.
3.4. StreamMessage
StreamMessage stores data as a sequence of typed fields, for example, JohnDoe33, defined as a sequence of two strings (John, Doe), and an integer (33).
3.5. ObjectMessage
ObjectMessage stores a serialized Java object.