友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
JMS简明教程(PDF格式)-第6部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
AND T F U
T T F U
F F F F
U U F U
表3�5 OR 操作的定义
OR T F U
T T T T
F T F U
U T U U
表3�6 NOT 操作的定义
NOT
T F
F T
U U
3。8。1。3 特别注意
当在消息选择器中使用 JMSDeliveryMode 时,它被看作值是’PERSISTENT’
和’NON_PERSISTENT’ 。
日期和时间值应当使用标准的Java long 毫秒值。当消息选择器中包含日期或时间文法
时,它的值应当是整型的。产生毫秒值得标准方式是使用java。util。Calendar 。
尽管 SQL 支持固定小数比较和算术运算,但JMS 消息选择器不支持。这是因为精确数
值是不能有小数的(而且,带小数的数值的加法是作为近似数值的备选呈现方式)。
不支持SQL 注释。
3。9 访问已发送的消息
在发送消息后,客户端可以保留和更改这个消息,但不影响已发送的消息。同一个消息
对象可以被多次发送。
在发送方法执行时,消息不能被客户端修改。如果修改了,则没有定义发送的结果是什
么。
27 / 66
…………………………………………………………Page 28……………………………………………………………
3。10 改变收到的消息的值
当接收到消息时,可以改变消息的头字段;但是他的属性和消息体是只读的,正如本章
所述。
限制只读是因为为了给 JMS 提供商在如何实现管理接收到的消息方面更多的自由。例
如,它们可以返回一个消息对象,这个对象引用位于内部消息缓冲区的属性条目和消息体的
值,而不需要返回一个拷贝。
在调研 clearBody 或clearProperties 方法使得消息体或属性可写后,消费者可以修改接
收到的消息。如果消费者更改了接收到的消息,且消息随后被转发,那么转发的消息必须是
原始的没有被改变的消息(除了被 JMS 提供商为转发而更改的头和属性外,例如
JMSRedilvered 头和JMSXDeliveryCount 属性)。
3。11 JMS 消息体
JMS 提供了五种形式的消息体。每种形式都由一个消息接口来定义:
z StreamMessage——消息体包含的是java 原始值流。它连续的填充和读。
z MapMessage——消息体包含一系列名字┲刀远渲忻质荢tring,值是Java 原
始类型。条目可以被枚举器连续获取也可以按名字随机获取。条目的顺序没有定义。
z TextMessage——消息体包含的是 java。lang。String 。这个消息类型是基于一个假设:
String 消息被广泛的使用。这是因为XML 很可能变成一个代表JMS 消息内容的流行
机制。
z ObjectMessage——消息包含了可序列化的 Java 对象。如果需要java 对象的集合,
那么可以使用在JDK1。2 中提供的集合类。
z BytesMessage——消息包含了一个未解释的字节流。这个消息类型用于按字面编码
的消息体去匹配一个存在的消息格式。在许多情况下,它可能用于一种其他未定义
的消息类型。尽管 JMS 允许消息属性使用字节消息,但通常不会使用,因为这样
可能影响消息的格式。
3。11。1 清除消息体
Message 的clearBody 方法重设消息体的值为’空’ 的初始化消息值,这个值由消息类型的
由Session 提供的创建方法设置。清除消息体不会清除它的属性条目。
3。11。2 只读消息体
当消息被接收时,它的消息体是只读的。如果企图改变消息体,那么必须抛出
MessageNotWriteableException。如果消息体随后被清除,那么消息体的状态和新创建消息时
的空消息体的状态一样。
28 / 66
…………………………………………………………Page 29……………………………………………………………
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�7 用于StreamMessage 和MapMessage 的转换
boolean byte short char int long float double String Byte''
boolean × ×
byte × × × × ×
short × × × ×
char × ×
int × × ×
long × ×
float × × ×
double × ×
String × × × × × × × ×
byte'' ×
3。11。4 用于非JMS 客户端的消息
很多企业消息系统支持自定义的 Stream 和/或 map 本地消息类型。尽管客户端可以使
用BytesMessage 来构造这种形式的本地消息,但JMS 为StreamMessage 和MapMessage 类
型提供了更加方便的API 。
例如,当客户端使用支持本地消息的JMS 提供商,且它希望发送既能被JMS 客户端又
能被本地客户端读取的map 消息时,它是由MapMessage。当消息被发送时,提供商将它转
换成本地格式。本地客户端然后就可以接收它。如果 JMS 提供商接收它,那么提供商将它
29 / 66
…………………………………………………………Page 30……………………………………………………………
转换回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 方法来访问消息体和消息属性内的对象。所有的这些方法必须
返回要获取对象的拷贝。
4 JMS 公共工具
4。1 概述
本章描述了在PTP 和Pub/Sub 域间共享的JMS 工具。
4。2 受管理的对象
JMS 受管理的对象是那些包含JMS 配置信息的对象,这些配置信息由JMS 管理员创建
然后由客户端使用。它们实际管理企业中的JMS 应用。
尽管受管理对象的接口不显式的依赖JNDI ,但JMS 为了JMS 客户端通过JNDI 查找的方
便而设置了这个方便性。
管理员可以将受管理对象放到命名空间的任何位置。JMS 没有定义命名策略。
30 / 66
…………………………………………………………Page 31……………………………………………………………
区分JMS 和管理提供了几个好处:
z 它对客户端隐藏了提供商特有的配置信息。
z 他将JMS 可管理的信息抽象成容易被通用管理控制台组织和管理的java 对象。
z 由于有JNDI 提供商提供所有流行的命名服务,那么这意味着JMS 提供商可以转发
一个受管理对象的实现,这些对象可以运行在任何地方。
受管理对象不能持有任何远程资源。它的lookup 不应当使用远程资源,除了有JNDI 自
己使用的资源以外。
客户端应当把受管理的对象看作是本地 java 对象。查找它们不应有任何隐藏边际影响
或使用大量的本地资源。
JMS 定义了两个手管理对象,Destination 和ConnectionFactory 。
期望JMS 提供商为管理员提供创建和在JNDI 命名空间中配置受管理对象的工具。JMS
提供商提供的手管理对象的实现应当是既javax。naming。Referencealbe 又java。io。Serializable 的,
以便它们能够被存储在所有的JNDI 命名上下文中。另外,建议这些实现遵循JavaBean 的设
计模式。
4。2。1 Destination
JMS 没有定义标准的地址语法。尽管考虑到了,但在现存的地址语义有很大差别的企业
消息产品间寻求一个单一的语法是不可能的。因此,JMS 定义了 Destination 对象来封装提
供商特有的地址作为替代方案。
由于 Destination 是一个受管理对象,因此它可以包含除了地址外的提供商特有的配置
信息。
JMS 也支持客户端使用提供商特有的地址名称。参加节4。4。4 “创建Destination 对象”
了解更详细的信息。
Destination 支持并发使用。
4。2。2 ConnectionFactory
ConnectionFactory 封装了一系列连接配置参数,这些参数由管理员定义。客户端使用它
来创建和JMS 提供商的连接。
ConnectionFactory 对象支持并发使用。
4。3 Connection
JMS Connection 是一个客户端到JMS 提供商间的活动连接。它通常分配在Java 虚拟机
外部的提供商的资源。
Connection 对象支持并发使用。
Connection 用作几个目的:
z 它封装了一个与 JMS 提供商的连接。他通常代表一个在提供商服务域和客户端间
的打开的TCP/IP Socket 。
z 在客户端授权时创建它。
z 它可以指定一个唯一的客户端标识。
31 / 66
…………………………………………………………Page 32……………………………………………………………
z 它创建Session 对象。
z 它提供ConnectionMetaData 。
z 它支持可选的ExceptionListener。
由于在创建Connection 时设置授权和通讯,因此Connection 相对是重量级的JMS 对象。
大多数客户端使用一个连接来执行所有的消息动作。其他更先进的应用可以使用多个
Connection 。JMS 使用多个连接不是架构方面的原因(除了当客户端作为两个不同提供商间
的网关时);但是可能有操作方面的原因。
4。3。1 授权
当创建连接时,客户端可以指定它的信任状如用户名/密码。
如果没有指定信任状,那么使用当前线程的信任状。这一点上,JDK 没有定义线程缺省
信任状的概念。但是在不久的将来可能会定义。目前,可以使用 JMS 客户端运行使用的用
户标识。
4。3。2 客户端标识
设置客户端标识的最好方式是将它配置在一个客户端特有的 ConnectionFactory 中,然
后透明的将它赋给它创建的连接。另一个方法就是客户端可以用提供商特有的值来设置连接
的客户端标识。显式地设置连接的客户端标识的工具不是一个用于覆盖已经被配置的标识的
机制。它只是用于管理员没有配置标识的情况。如果标识已经存在,那么企图更改它必须抛
出IllegalStateException。
如果客户端显式地设置标识,那么它必须在创建连接后和在连接上发生其他动作之前立
即设置。如果在这个时刻后再设置,则设置客户端标识就是程序性错误,将抛出
IllegalStateException。
客户端标识的目的是将连接和它的对象与由提供商按客户端维护的状态关联起来。按照
定义,被客户端标识标识的客户端状态在一个时刻只能由一个客户端“在用”。JMS 提供商
必须防止并发执行的客户端来使用它。
阻止方式可以是当企图这样使用时抛出各种 JMSException 的形式;也可以阻塞后续的
客户端;或者是其他的解决方案。JMS 提供商必须保证这种共享单个客户端状态的企图不能
引起消息的丢失或重复处理。
由JMS 标识的唯一的单个客户端状态要支持长期订阅。
4。3。3 Connection 设置
JMS 客户端通常创建一个 Connection,一个或多个Session 和大量的 MessageProducer
和MessageConsumer。当Connection 被创建时,它处于stopped 模式。意思是没有消息可以
转发给它。
通常会让昂Connection 处于停止模式直到设置完成。设置完成后调用Connection。start()
方法,且消息开始到达 Connection 的消费者。这种设置约定减小了客户端还在设置它自己
时就有异步消息转发的问题。
Connection 可以立即启动然后再进行设置。这样,客户端必须做好它们在设置过程中处
32 / 66
…………………………………………………………Page 33……………………………………………………………
理异步消息转发的准备。
MessageProducer 可以在Connection 是停止时发送消息。
要注意,客户端必须在连接启动后它才能转发消息。JMS 提供商必须保证这种情况。
4。3。4 中止消息的转发
连接对接收到的消息的转发可以使用 stop()方法被临时停止。可以使用 start()方法重新
启动它。当连接被停止时,禁止向所有连接的 MessageConsumer 进行转发:同步接收被阻
塞,消息不被转发到MessageListener。
停止连接对发送消息没有影响。停止一个已经停止的连接和启动一个已经启动的连接被
忽略。
在消息的转发被停止后才能返回 stop 方法。这意味着停止后,不会调用任何消息监听
器,并且所有的等待接收消息的控制线程在连接重新启动前不会返回消息。用于已停止连接
的的接收计时器仍然有效,因此接收可能会超时并返回一个空消息。
如果stop 方法被调用时消息监听器(Message
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!