在你开始前
了解对本教程有什么期望,以及如何充分利用本教程。
关于本教程
本教程概述了统一域接口,它们是Java消息服务(JMS)1.1客户端编程的首选方法。 随附示例应用程序以及有关运行这些应用程序的说明,以演示和测试这些接口的功能和使用。 本教程还展示了如何将IBM WebSphere MQ配置为Rational Application Developer(应用程序开发者)WebSphere Test Environment的JMS提供者,以及使用该配置运行应用程序的说明。
目标
完成本教程后,您将知道如何:
- 使用JMS统一域接口
- 将WebSphere MQ配置为Application Developer WebSphere测试环境的JMS提供者
先决条件
本教程适用于需要了解如何使用WebSphere MQ和Rational Application Developer编写和测试JMS程序的Java程序员。 假定您具有Java的中级知识和JMS的入门知识。 本教程中的说明还假定您已阅读并执行了第1 部分和第2 部分中的说明,因为它们是基于在这些教程中创建和测试的配置以及示例代码构建的。
系统要求
本教程中的说明适用于Windows环境,尽管精通其他操作系统的读者也可以将其改编为在其操作系统中使用。
可通过以下链接找到本教程中使用的产品的系统要求:
在本系列的第1部分中,您将简要概述企业消息传递系统和JMS。 它提供了IBM用于JMS开发和测试的最新工具的描述,并提供了有关获取,安装和配置这些工具的详细说明。 提供了示例程序和有关运行它们的说明,以练习工具并了解其工作方式。
在本系列的第2部分中,您将了解WebSphere MQ客户端传输和远程排队以及JMS发布/订阅应用程序。 它提供了有关配置这些功能的分步说明,并提供了示例程序来演示其用法。
本部分(第3部分)将从这些教程中停下来的地方继续学习,以进一步探索使用Rational Application Developer的WebSphere MQ和JMS编程。 本教程中的说明假定您已阅读并执行了前两个教程中的说明,因为第3部分建立在这些教程中创建和测试的配置和示例代码的基础上。
JMS 1.1统一域通用接口
JMS 1.0提供了高级接口,它们是点对点和发布/订阅特定于域的接口的父级。 这些接口仅包含两个域共有的那些功能,并且JMS提供程序未提供这些接口的实现。 在JMS 1.1中,高级接口现在被认为是通用接口,并且包含两个域的所有功能。 JMS提供程序必须提供这些接口的实现。 尽管公用接口仍然是特定于域的接口的父级,但是它们现在是JMS客户端编程的首选方法,并且仅提供特定于域的接口是为了向后兼容。 通用接口统一了JMS域,从而提供了更轻松的编程和更灵活的应用程序。
下表显示了公共接口和从每个接口继承的特定于域的接口。
表1.通用接口和相应的特定于域的接口
JMS通用接口 | 点对点域 | 发布/订阅域 |
---|---|---|
连接工厂 | QueueConnectionFactory | TopicConnectionFactory |
连接 | 队列连接 | TopicConnection |
目的地 | 队列 | 话题 |
届会 | 队列会话 | TopicSession |
消息制作人 | 队列发送者 | 主题发布者 |
MessageConsumer | QueueReceiver,QueueBrowser | 主题订阅者 |
查看公共接口示例代码
为了更好地说明统一域编程,我修改了先前教程中的示例代码,使其仅使用公共接口。 在本部分中,您将导入此示例代码并查看其中的部分内容,以更好地理解使用公共接口。
所有代码都打包在应用程序客户端模块中,以便使用WebSphere Test Environment运行它。
安装示例代码
- 下载名为i-mqrad3code.zip的示例代码文件。 (单击可下载资源以获取链接)。 在我的系统上,我将其下载到Windows桌面上名为i-mqrad3code的文件夹中。
- 如果尚未启动,请从Windows的“开始”菜单启动Rational Application Developer。 (从这时开始,说明将假定Application Developer正在运行。)
- 在Application Developer中,从主菜单中选择File> Import 。
- 选择Project Interchange作为导入源,然后单击Next 。
- 在“ 从zip文件中”字段中,输入i-mqrad3code.zip文件的位置。
- 单击全选 ,然后单击完成 。
QSender类
看第一类是QSender
在EQSenderCommon项目。 首先查看清单1所示的JMS实例变量。
清单1. JMS实例变量
public class QSender {
private Connection connection;
private Session session;
private MessageProducer sender;
如您所见,我已经用普通接口类型的变量完全替换了EQSender项目中QSender
类中使用的点对点接口类型的变量。
现在看一下清单2所示的setConnection()
方法。
清单2. setConnection()方法
public void setConnection(String connectionName) throws JMSException,
NamingException, Throwable {
try {
close();
ConnectionFactory factory = (ConnectionFactory) getInitContext()
.lookup(connectionName);
connection = factory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
} catch (Throwable e) {
setExceptionMessage(e);
throw e;
}
}
此代码等效于MQP2P项目中QSender
类中的setConnection()
方法,但仅使用公共接口。
在QSender
类中查看的最后一个方法是setQueue()
,如清单3所示。
清单3. setQueue()方法
public void setQueue(String queueName) throws JMSException,
NamingException, Throwable {
try {
if (connection != null)
connection.stop();
if (sender != null)
sender.close();
Destination queue = (Destination) getInitContext()
.lookup(queueName);
sender = session.createProducer(queue);
sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
sender.setPriority(4);
sender.setTimeToLive(0);
connection.start();
} catch (Throwable e) {
setExceptionMessage(e);
throw e;
}
}
再一次,仅使用通用接口类型。 但是请注意,我将变量名保持不变,因为从语义上讲,该程序旨在用于点对点消息传递。 但是,使用公共接口可以在运行时提供更大的灵活性,正如您在运行此代码时所看到的。
QReceiver类
到目前为止,您应该已经明白了—这个新的示例代码仅使用统一域通用接口。 但是,看看EQReceiverCommon项目(如清单4所示setQueue()
中的QReceiver
类中的setQueue()
方法只是为了强调这一点。
清单4. QReceiver方法
public void setQueue(String queueName) throws JMSException,
NamingException, Throwable {
try {
if (connection != null)
connection.stop();
if (receiver != null)
receiver.close();
Destination queue = (Destination) getInitContext()
.lookup(queueName);
receiver = session.createConsumer(queue);
receiver.setMessageListener(this);
connection.start();
} catch (Throwable e) {
setExceptionMessage(e);
throw e;
}
}
尽管该变量名为queue
,但实际上它的类型为Destination
,即Queue
的父接口。 同样, receiver
变量是MessageConsumer
,它是QueueReceiver
的父接口。
ChatMonitor类
再看看EChatMonitorCommon项目的ChatMonitor
类中的另一个方法,即onMessage()
方法,如清单5所示。
清单5. onMessage()方法
public void onMessage(Message message) {
String msgText = null;
try {
//msgText =
// (((Topic) message.getJMSDestination()).getTopicName()
// + ": "
// + ((TextMessage) message).getText());
msgText = ((TextMessage) message).getText();
} catch (Throwable e) {
setExceptionMessage(e);
msgText = getExceptionMessage();
} finally {
setMessage(msgText);
}
}
请注意已注释掉的代码。 在本系列第2部分中的代码版本中,我可以将对message.getJMSDestination()
的调用接收到的Destination
转换为Topic
,因为消息来自主题,因为我使用以下域编写了代码:特定的发布/订阅界面。 现在,我已经更改了代码以使用公共接口,现在我不能做那个假设了。 如果我确定当消息确实来自某个主题时我绝对想显示该主题名称,则可以尝试强制转换并在该消息来自队列时捕获ClassCastException
,用适当的文本替换该主题名称。
在本教程中,我不会再讨论任何代码,但我建议您检查所有新的示例代码,以了解通用接口的用法并加深对它们的了解。
运行公共接口示例代码
在本节中,您将运行用通用接口编写的点对点程序,以查看它们是否像以前一样工作,并且将运行用通用接口编写的发布/订阅程序,并验证它们的行为与发布/订阅程序相同表现在上一教程中。 然后,您将一起运行所有程序,并看到使用统一域公用接口的真正功能和灵活性。
运行点对点程序
运行EQReceiverCommon
- 在Application Developer中,确保您在J2EE透视图中。
- 选择窗口底部的“ 服务器”视图。
- 右键单击WebSphere Application Server v6.0,然后选择启动 。
- 等待服务器的状态更改为已启动。
- 右键单击EQReceiverCommon,然后选择运行>运行 。
- 在“ 配置”列表中选择WebSphere v6.0 Application Client 。
- 点击新建 。
- 将名称字段更改为
EQReceiverCommon
。 - 点击运行 。
- 在“ 连接”字段中键入
jms/BeanQCF
,然后按Enter或单击“ 设置” 。 - 在Queue字段中输入
jms/MyBeanQ
,然后按Enter或单击Set 。
运行EQSenderCommon
- 返回Application Developer,右键单击EQSenderCommon,然后选择Run> Run 。
- 在“ 配置”列表中选择WebSphere v6.0 Application Client 。
- 点击新建 。
- 将“ 名称”字段更改为
EQSenderCommon
。 - 点击运行 。
- 在“ 连接”字段中键入
jms/BeanQCF
,然后按Enter或单击“ 设置” 。 - 在Queue字段中输入
jms/MyBeanQ
,然后按Enter或单击Set 。
测试程序
- 使“队列发送者”和“队列接收器”窗口均可见。
- 在“队列发件人”的“ 消息”字段中键入文本,然后按Enter或单击“ 设置” 。
- 您应该看到消息文本出现在“队列接收器”窗口中。
- 完成后,请同时打开两个窗口。
运行发布/订阅程序
让我们尝试发布/订阅程序。
运行EChatCommon
- 右键单击EChatCommon,然后选择运行>运行 。
- 在“ 配置”列表中选择WebSphere v6.0 Application Client 。
- 点击新建 。
- 在名称字段中输入
EChatCommon
。 - 点击运行 。
- 在“聊天”窗口的“ 用户名”字段中键入
User1
,然后按Enter或单击“ 设置” 。 - 在连接字段中输入
jms/BeanTCF
,然后按Enter或单击设置 。 - 在主题字段中输入
jms/Java
,然后按Enter或单击设置 。 - 您将看到消息:“ User1已进入聊天室”。
- 在Application Developer中,从主菜单中选择Run> Run History> EChatCommon 。
- 在第二个“聊天”窗口中,在“ 用户名”字段中键入
User2
,然后按Enter或单击“ 设置” 。 - 在连接字段中输入
jms/BeanTCF
,然后按Enter或单击设置 。 - 在主题字段中输入
jms/Java
,然后按Enter或单击设置 。 - 您将在两个“聊天”窗口中看到消息“用户2已进入聊天室”。
- 在任一窗口的消息字段中,键入任何文本,然后按Enter或单击发送 。 消息文本将在两个窗口中显示,并以发布消息的用户名作为前缀。
- 尝试将每个窗口中的主题更改为使用JMSAdminGUI创建的其他主题之一。 但是,请勿尝试使用jms / AllComputers或jms / AllBooks,因为发布不允许通配(*)主题,只能订阅。
- 另外,请尝试使用其他用户名运行其他
EChatCommon
实例。 - 在继续下一步之前,将其中一个“聊天”窗口上的主题更改为Java。
运行EChatMonitorCommon
- 返回到应用程序开发人员。
- 从主菜单中,选择运行>运行 。
- 在“ 配置”列表中右键单击EChatCommon ,然后选择“ 重复” 。
- 将EChatCommon(1)重命名为
EChatMonitor
。 - 将“ 应用程序客户端模块”字段更改为
EChatMonitorCommon
。 - 点击运行 。
- 在“聊天监视器”窗口的“ 连接”字段中键入
jms/BeanTCF
,然后按Enter或单击“ 设置” 。 - 在主题字段中输入
jms/AllComputers
,然后按Enter或单击设置 。 - 切换到使用jms / Java主题的“聊天”窗口,确保“聊天监视器”窗口可见并发送消息。
- 消息文本将显示在“聊天监视器”窗口中,该消息文本之前是发布消息的用户。
- 切换到使用jms / Java主题的“聊天”窗口,然后在“ 主题”字段中键入
jms/Linux
,然后按Enter或单击Set 。 - 从该“聊天”窗口发送消息。
- 消息文本将显示在“聊天监视器”窗口中。
- 在使用jms / Linux主题的“聊天”窗口中,键入
jms/Cyberpunk
,然后按Enter或单击Set 。 - 从该“聊天”窗口发送消息。
- 您不会在“聊天监视器”窗口中看到该消息。
- 完成后,通过单击右上角的X关闭以jms / Cyberpunk为主题的“聊天”窗口。 让一个“聊天”窗口和“聊天监视器”窗口保持打开状态。 确保打开的“聊天”窗口使用jms / Java作为主题。
连连看
在这一点上,您可能在想:“ Ho,我明白了。我可以使用公共接口来获得与特定于域的接口相同的行为。” 但是,等等,还有更多。
让我们玩得开心。 在本系列的前一部分中,点对点程序无法与发布/订阅程序进行通信,因为它们是为特定域编写的。 新的示例程序没有此限制,您很快就会发现。
- 切换到“队列接收器”窗口,然后在“ 队列”字段中键入
jms/Java
,然后按Enter或单击“ 设置” 。 - 切换到Queue Sender窗口,并在Connection字段中输入
jms/BeanTCF
,然后按Enter或单击Set 。 - 仍然在Queue Sender窗口中,在Queue字段中输入
jms/Java
,然后按Enter或单击Set 。 - 从“队列发件人”窗口发送消息。 其他三个窗口都应收到该消息。
- 切换到“聊天”窗口,然后发送一条消息。 聊天监视器和队列接收器应收到该消息。
- 仍在“聊天”窗口中,在“ 主题”字段中键入
jms/MyBeanQ
,然后按Enter或单击“ 设置” 。 - 切换到Queue Receiver窗口,
jms/MyBeanQ
在Queue窗口中键入jms/MyBeanQ
,然后按Enter或单击Set 。 - 切换到“聊天”窗口并发送消息。 队列接收器应收到该消息。
- 完成后,通过单击右上角的X关闭所有窗口,然后停止服务器。
当说明告诉您在点对点程序中键入TopicConnectionFactory
的名称或在发布/订阅程序中键入Queue
的名称时,您可能会感到惊讶。 但这就是重点。 ConnectionFactory
是ConnectionFactory
,无论是QueueConnectionFactory
还是TopicConnectionFactory
。 Destination
就是Destination
,无论是Topic
还是Queue
。
通过该演示,您现在应该开始真正地了解统一域通用接口的功能,灵活性和多功能性。
WebSphere MQ作为WebSphere Test Environment JMS提供者
到目前为止,您已经在SupportPacs的帮助下直接使用WebSphere MQ进行JMS编程,SupportPacs在WebSphere MQ中提供了Java命名和目录接口(JNDI)功能,并且已经使用了WebSphere的内置JMS消息传递功能。测试环境。 在本部分中,您将配置WebSphere MQ为WebSphere Test Environment的JMS提供者。 由于WebSphere Test Environment实际上是WebSphere Application Server V6,因此这些说明适用于将WebSphere MQ用作WebSphere Application Server V6的JMS提供程序。
WebSphere MQ修订包6.0.1.1
坦率地说,在我开发和测试本教程的这一部分时,遇到了一些错误,使我感到困惑。 我做了一些研究,发现自己没有犯错误,但是我尝试做的事情存在一个已知问题。 幸运的是,该问题已通过WebSphere MQ Fix Pack 6.0.1.1得到纠正。 在继续之前,您必须在系统上安装此修订包。 (有关链接,请参阅可下载资源 。)按照修订包随附的说明进行安装。 您不必安装修订包随附的更新的Java SDK。
一旦安装了修订包,您可能必须重新引导系统。 如果是这样,请重新启动Application Developer。 无论是否重新引导,请按照本教程第2部分中的说明,使用strmqbrk -m Ender
命令重新启动代理。
配置WebSphere MQ
更改WebSphere MQ安装变量
安装后,WebSphere Test Environment使用Application Developer提供的WebSphere MQ和JMS库。 为了使测试环境正确使用WebSphere MQ,它必须使用WebSphere MQ提供的库。 这是在测试环境中更改变量的简单问题。
- 在Application Developer中,确保您在J2EE透视图中。
- 选择服务器视图。
- 右键单击WebSphere Application Server v6.0,然后选择启动 。
- 等待服务器的状态更改为已启动。
- 右键单击服务器,然后选择“运行管理控制台” 。
- 出现控制台时,使用任何用户ID登录。
- 在左侧的导航栏中单击环境 。
- 单击WebSphere变量 。
- 单击变量列表中的MQ_INSTALL_ROOT链接。
- 将Value字段更改为
C:\WSMQ
(请参见图1 )。图1.更改MQ_INSTALL_ROOT变量
- 单击确定 。
- 点击保存在页面的顶部,然后单击保存按钮。
创建JMS管理的对象
- 在左侧导航栏中,单击资源> JMS提供程序> WebSphere MQ 。
- 单击“ 其他属性”列表中的WebSphere MQ连接工厂 。
- 点击新建 。
- 在名称字段中输入
WigginsCF
。 - 在“ JNDI名称”字段中输入
jms/WigginsCF
。 - 在“ 队列管理器”字段中输入
Ender
(请参见图2 )。图2.配置WebSphere MQ连接工厂
- 在WebSphere MQ中使用内置消息代理时,需要进行以下两项更改。 使用单独的消息代理(例如WebSphere Event Broker)时,将使用不同的值。
- 将Broker版本更改为Basic 。
- 将Broker消息选择更改为Client 。 (请参见图3 )。
图3.配置WebSphere MQ连接工厂(续)
- 单击确定 。
- 单击左侧导航栏上的WebSphere MQ 。
- 在其他属性列表中,单击WebSphere MQ队列目标 。
- 点击新建 。
- 在名称字段中输入
WigginsQ
。 - 在“ JNDI名称”字段中键入
jms/MyWigginsQ
。 - 在基本队列名称字段中输入
EnderQ
。 (请参见图4 )。图4.配置WebSphere MQ队列目标
- 单击确定 。
- 再次单击新建 。
- 在名称字段中输入
DemosthenesQ
。 - 在“ JNDI名称”字段中键入
jms/MyDemosthenesQ
。 - 在基本队列名称字段中输入
RemotePetraQ
。 (参见图4。 ) - 单击确定 。
- 单击左侧导航栏上的WebSphere MQ 。
- 在其他属性列表中,单击WebSphere MQ主题目标 。
- 点击新建 。
- 在名称字段中输入
Locke
。 - 在“ JNDI名称”字段中输入
jms/Locke
。 - 在基本主题名称字段中输入
computers/java
。 - 单击确定 。
- 点击保存在页面的顶部,然后单击保存按钮。
- 退出管理控制台。
- 在“ 服务器”视图中右键单击WebSphere Application Server v6.0 ,然后选择重新启动>启动 。
运行示例代码
现在,您可以运行示例程序来测试配置。 正如您必须更改WebSphere Test Environment以使用WebSphere MQ库一样,您还必须更改应用程序客户机模块以使用那些相同的库。
运行发布/订阅示例程序
- 在Application Developer中,从主菜单中选择Run> Run 。
- 在“ 配置”列表中选择EChatCommon 。
- 单击参数选项卡。
- 将-Dws.ext.dirs参数中的条目从
C:\RAD\runtimes\base_v6\lib\WMQ\java\lib
更改为C:\WSMQ\Java\lib
。 (参见图5。 )图5.配置EChatCommon VM参数
- 点击运行 。
- 在“聊天”窗口的“ 用户名”字段中键入
User1
,然后按Enter或单击“ 设置” 。 - 在连接字段中输入
jms/WigginsCF
,然后按Enter或单击设置 。 - 在主题字段中输入
jms/Locke
,然后按Enter或单击设置 。 - 您将看到消息“用户1已进入聊天室”。
- 在Application Developer中,从主菜单中选择Run> Run History> EChatCommon 。
- 在第二个“聊天”窗口中,在“ 用户名”字段中键入
User2
,然后按Enter或单击“ 设置” 。 - 在连接字段中输入
jms/WigginsCF
,然后按Enter或单击设置 。 - 在主题字段中输入
jms/Locke
,然后按Enter或单击设置 。 - 您将在两个“聊天”窗口中看到消息“用户2已进入聊天室”。
- 在任一窗口的消息字段中,键入任何文本,然后按Enter或单击发送 。 消息文本将在两个窗口中显示,并以发布消息的用户名作为前缀。
- 完成后,通过单击右上角的X关闭所有窗口。
运行点对点示例代码
- 从主菜单中选择运行>运行 。
- 在“ 配置”列表中选择EQReceiverCommon 。
- 单击参数选项卡。
- 将-Dws.ext.dirs参数中的条目从
C:\RAD\runtimes\base_v6\lib\WMQ\java\lib
更改为C:\WSMQ\Java\lib
。 - 点击运行 。
- 在连接字段中输入
jms/WigginsCF
,然后按Enter或单击设置 。 - 在队列字段中输入
jms/MyWigginsQ
,然后按Enter或单击设置 。 - 从主菜单中选择运行>运行 。
- 在“ 配置”列表中选择EQSenderCommon 。
- 单击参数选项卡。
- 将-Dws.ext.dirs参数中的条目从
C:\RAD\runtimes\base_v6\lib\WMQ\java\lib
更改为C:\WSMQ\Java\lib
。 - 点击运行 。
- 在连接字段中输入
jms/WigginsCF
,然后按Enter或单击设置 。 - 在队列字段中输入
jms/MyWigginsQ
,然后按Enter或单击设置 。 - 使“队列发送者”和“队列接收器”窗口均可见。
- 在“队列发件人”的“ 消息”字段中键入文本,然后按Enter或单击“ 设置” 。
- 您应该看到消息文本出现在“队列接收器”窗口中。
- 完成后,关闭两个窗口。
再次混合搭配
最后,我们将使用不同的JNDI环境和远程排队来运行程序,只是为了展示WebSphere MQ的一些功能。
- 从Windows“开始”菜单启动WebSphere MQ Explorer。
- 选择Ender队列管理器下的Channels 。
- 右键单击Ender_2_Petra,然后选择开始 。
- 在Application Developer中,从主菜单中选择Run> Run 。
- 选择QReceiverUI并单击运行 。
- 在“ 连接”字段中键入
Petra
,然后按Enter或单击“ 设置” 。 - 在“ 队列”字段中键入
PetraQ
,然后按Enter或单击“ 设置” 。 - 从主菜单中,选择运行>运行历史记录> EQSenderCommon 。
- 在连接字段中输入
jms/WigginsCF
,然后按Enter或单击设置 。 - 在队列字段中输入
jms/MyDemosthenesQ
,然后按Enter或单击Set 。 - 使“队列发送者”和“队列接收器”窗口均可见。
- 在“队列发件人”的“ 消息”字段中键入文本,然后按Enter或单击“ 设置” 。
- 您应该看到消息文本出现在“队列接收器”窗口中。
- 完成后,关闭两个窗口。
摘要
在本教程中,您选择了第2部分的开头,并探讨了JMS编程中的其他一些主题:JMS 1.1统一域编程接口,以及将WebSphere MQ用作Application Developer WebSphere Test Environment的JMS提供者。
尽管我们还没有涵盖使用IBM工具进行JMS编程的所有知识,但是您现在应该具有将IBM产品用于企业消息传递和JMS编程的良好基础,并且可以开始在自己的应用程序中使用这些技术。
翻译自: https://www.ibm.com/developerworks/websphere/tutorials/i-mqrad3/i-mqrad3.html