16boke - 一路博客

JMS消息体

JMS提供了五种形式的消息体。每种形式都由一个消息接口来定义:

• StreamMessage——消息体包含的是java原始值流。它连续的填充和读。

• MapMessage——消息体包含一系列名字‐值对儿,其中名字是String,值是Java原始类型。条目可以被枚举器连续获取也可以按名字随机获取。条目的顺序没有定义。

• TextMessage——消息体包含的是java.lang.String。这个消息类型是基于一个假设:String消息被广泛的使用。这是因为XML很可能变成一个代表JMS消息内容的流行机制。

• ObjectMessage——消息包含了可序列化的Java对象。如果需要java对象的集合, 那么可以使用在JDK1.2中提供的集合类。

• BytesMessage——消息包含了一个未解释的字节流。这个消息类型用于按字面编码 的消息体去匹配一个存在的消息格式。在许多情况下,它可能用于一种其他未定义的消息类型。尽管JMS 允许消息属性使用字节消息,但通常不会使用,因为这样可能影响消息的格式。

3.11.1 清除消息体

Message的clearBody方法重设消息体的值为’空’的初始化消息值,这个值由消息类型的由Session 提供的创建方法设置。清除消息体不会清除它的属性条目。

3.11.2 只读消息体

当消息被接收时,它的消息体是只读的。如果企图改变消息体,那么必须抛出MessageNotWriteableException。如果消息体随后被清除,那么消息体的状态和新创建消息时 的空消息体的状态一样。

3.11.3 由StreamMessage和MapMessage提供的转换

StreamMessage和MapMessage都支持相同的原始数据类型集合。这些类型可以被显式地使用类型对应的方法来读写。它们也可以都作为对象被读写。例如,调用MapMessage.setInt(“foo”,6)等价于MapMessage.setObject(“foo”,new Integer(6))。提供两种形式是因为显式的方式对静态的编程更方便,但对象形式在编译时不知道类型时是需要的。

StreamMessage和MapMessage都支持下面的转换表。

标记为大写的必须支持。其他的必须抛出MessageFormatException。如果传入数值的valueOf 方法的String是无效的,那么String 到数值的转换必须抛出java.lang.NumberFormatException。

StreamMessage和MapMessage必须实现String到布尔的转换,那和在Java语言中定义 的Boolean的valueOf(String)转换一样。

企图读取null值作为java的原始类型必须看作用null值调用原始类型对应的valueOf(String)方法。由于char不支持String转换,因此企图读取null值作为char必须抛出 NullPointerException。

用名字获取还没有被设值的MapMessage字段按照null值处理。

如果StreamMessage使用BytesMessage的读方法抛出MessageFormatException或NumberFormatException,那么不能增加读指针所在的位置。随后的读必须能够通过重读数据作为不同的类型而从异常中恢复。

用行类型写的值可能被读作列类型。

3.11.4 用于非JMS客户端的消息

很多企业消息系统支持自定义的Stream和/或map本地消息类型。尽管客户端可以使用BytesMessage 来构造这种形式的本地消息,但JMS为StreamMessage和MapMessage类型提供了更加方便的API。

例如,当客户端使用支持本地消息的JMS提供商,且它希望发送既能被JMS客户端又能被本地客户端读取的map 消息时,它是由MapMessage。当消息被发送时,提供商将它转换成本地格式。本地客户端然后就可以接收它。如果JMS 提供商接收它,那么提供商将它转换回MapMessage。

即使实现使用新定义的消息的新JMS应用时,应用可以选择使用StreamMessage和MapMessage 来保证非JMS客户端能够读取消息。

如果JMS客户端发送StreamMessage或MapMessage,那么它必须被接收JMS提供商转换成一个等价的StreamMessage或MapMessage。当在JMS客户端间传递时,消息必须保持 它全部的格式。例如,作为MapMessage发生的消息不能作为BytesMessage消息被接收。

如果JMS提供商接收一个由本地客户端创建的消息,那么提供商应当将它尽力转换成“最佳的”JMS 消息类型。例如,如果是本地流消息,那么它应当被转换成StreamMessage。如果转换不了,那么提供商总能够将它转换成BytesMessage。

3.12 JMS Message接口的提供商实现

JMS提供了一系列消息接口,这些接口定义了JMS消息模型。它没有提供这些接口的实现。

每个JMS提供商提供它自己的会话的消息创建方法的实现。这可以让提供商来使用满足它需要的消息实现。

提供商必须能够从客户端接收不是它自己的消息实现。提供商可以不高效的处理外来消息实现,但它必须处理。

当提供商处理外来消息实现时需要注意下面的例外情况。如果外来消息实现包含JMSReplyTo 头字段,这个字段设置了外来地址实现,那么不要求提供商处理或保存这个头字段的值。

JMS消息接口提供了写/set方法来设置消息体内和消息属性内的对象的值。所有的这些 方法必须复制它们输入的对象,然后放进消息中。输入对象的值可以是null,当获取时返回 null。一个例外是BytesMessage不支持空流的概念,因此企图向他写null则必须抛出 java.lang.NullPointerException。

JMS消息接口提供读/get方法来访问消息体和消息属性内的对象。所有的这些方法必须返回要获取对象的拷贝。