http://blog.csdn.net/liaomin416100569/article/details/7254191
首先 打开 IBM websphere MQ 管理器 添加一个队列管理器 名称 叫MyTest
在队列管理气中的队列文件夹下 新建一个本地队列名称叫 LOCALQUEUE
在高级-》通道 下新建一个服务器连接通道 名称叫:SERVERCONN
在mytest右键 属性 查看编码字符集标识 中文默认在window下是 1381
在高级-》侦听器下查看连接的端口 默认是:1414
编写代码:
package com.mq;
import com.ibm.mq.MQC;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
public class TestMQ {
static MQQueueManager qMgr;
static int CCSID=1381 ;
static String queueString="LOCALQUEUE";
public static void connect() throws MQException {
MQEnvironment.hostname = "127.0.0.1";
MQEnvironment.channel = "SERVERCONN";
MQEnvironment.port = 1414;
MQEnvironment.CCSID = CCSID;
qMgr = new MQQueueManager("myTest");
}
public static void sendMsg(String msgStr){
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF|MQC.MQOO_OUTPUT|MQC.MQOO_INQUIRE;
MQQueue queue = null;
try {
//建立Q1通道的连接
queue = qMgr.accessQueue(queueString, openOptions, null, null,null);
MQMessage msg = new MQMessage();// 要写入队列的消息
msg.format = MQC.MQFMT_STRING;
msg.characterSet = CCSID;
msg.encoding=CCSID;
// msg.writeObject(msgStr); //将消息写入消息对象中
msg.writeString(msgStr);
MQPutMessageOptions pmo = new MQPutMessageOptions();
msg.expiry = -1; // 设置消息用不过期
queue.put(msg, pmo);// 将消息放入队列
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(queue!=null){
try {
queue.close();
} catch (MQException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void receiveMsg()
{
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF|MQC.MQOO_OUTPUT|MQC.MQOO_INQUIRE;
MQQueue queue = null;
try {
queue = qMgr.accessQueue(queueString, openOptions, null, null,null);
System.out.println("该队列当前的深度为:"+queue.getCurrentDepth());
System.out.println("===========================");
int depth = queue.getCurrentDepth();
//将队列的里的消息读出来
while(depth-->0)
{
MQMessage msg = new MQMessage();// 要读的队列的消息
MQGetMessageOptions gmo = new MQGetMessageOptions();
queue.get(msg, gmo);
System.out.println("消息的大小为:"+msg.getDataLength());
System.out.println("消息的内容:\n"+msg.readStringOfByteLength(msg.getDataLength()));
System.out.println("---------------------------");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(queue!=null){
try {
queue.close();
} catch (MQException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws MQException {
connect();
sendMsg("fuck 你大爷的");
receiveMsg();
}
}
====================
http://www.ibm.com/developerworks/cn/java/wa-spring4/index.html
在 Spring 系列 的第 4 期也是最后一期中,我将介绍 Spring JMS(Java 消息服务)框架的特性。JMS PG 定义了 Java 应用程序通过面向消息的中间件(MOM)创建和交换消息的标准途径。
就像在这个系列前面的文章中一样,我将使用一个简单的示例来演示 Spring JMS 的特性。您将随我一道开发一个点对点的(P2P)基于消息的系统,使用 Spring JMS 框架通过 JMS 接口与 IBM 的 WebSphere MQ 集成。完成练习后,将可以通过这个系统发送和接收简单的文本消息。
在开始之前,请 下载文章的源代码。请参阅 参考资料 访问 Spring 框架和 IBM WebSphere MQ 5.3。还需要 Apache Ant 来运行示例应用程序。
Spring 的 JMS 抽象框架简化了 JMS API 的使用,并与 JMS 提供者(比如 IBM 的 WebSphere MQ 5.3)平滑地集成。org.springframework.jms.core 包提供了在 Spring 中使用 JMS 的核心功能。它的模板类处理资源的创建和释放,简化了 JMS 的使用。
像其他大多数 Spring 模板类一样,JMS 模板类提供了执行公共操作的 helper 方法。在需要更复杂应用的情况下,类把处理任务的核心委托给用户实现的回调接口。JMS 类提供了方便的方法,用来发送消息、同步地使用消息以及向用户公开 JMS 会话和消息的制作者。
以下 JMS 包和 org.springframework.jms.core 一起构成了 Spring JMS 的功能:
-
org.springframework.jms.support
-
提供转换
JMSException
的功能。转换代码把检测到的JMSException
层次结构转换成未检测到异常的镜像层次结构。
org.springframework.jms.support.converter
-
提供
MessageConverter
抽象,以在 Java 对象和 JMS 消息之间进行转换。
org.springframework.jms.support.destination
- 提供管理 JMS 目标的不同策略,比如针对 JNDI 中保存的目标的服务定位器。 org.springframework.jms.connection
-
提供适合在独立应用程序中使用的
ConnectionFactory
实现。connection 还包含针对 JMS 的 SpringPlatformTransactionManager
实现。它允许把 JMS 作为事务性资源集成到 Spring 的事务管理机制中。
就像前面提到的,示例应用程序会用 Spring 的 JMS 框架通过 JMS 接口与 IBM 的 WebSphere MQ 集成。通过在应用程序和 Web 服务之间传递消息,WebSphere MQ 提供了可靠的、有恢复能力的应用程序集成。它使用队列和事务性工具帮助保持消息跨网络的完整性。WebSphere MQ 降低了信息丢失的风险和调和通信 IT 系统的需要。
WebSphere MQ 在它所支持的所有平台上提供了一致的应用程序编程接口,这有助于让集成的程序可移植。除了标准接口外,WebSphere MQ 还完整实现了JMS 接口,包括对发布-订阅消息传递的支持。WebSphere MQ Explorer 工具可以远程地管理和配置整个 MQ 网络。管理和配置工具基于开放源码的 Eclipse 框架,而且是可扩展的。
Spring 框架提供了 JmsTemplate
的两个实现。JmsTemplate
类使用 JMS 1.1 API,子类 JmsTemplate102
则使用 JMS 1.0.2 API。我的示例应用程序使用的是 JmsTemplate102
。
JMS 模板被用来发送和接收 JMS 消息。Spring 采用回调机制对 JMS 信息传递进行协调。MessageCreator
回调接口用 JmsTemplate
中的调用代码提供的 Session
创建消息。为了支持 JMS API 更复杂的应用,回调 SessionCallback
向用户提供了 JMS 会话,而 callback ProducerCallback
则公开了 Session
和 MessageProducer
组合。
清单 1 显示了示例应用程序使用的 JMS 模板的配置。清单摘自 spring-mqseries-jms.xml 文件(请参阅 下载)。
<!-- JMS Queue Template --> <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate102"> <property name="connectionFactory"> <ref bean="jmsQueueConnectionFactory"/> </property> <property name="destinationResolver"> <ref bean="jmsDestinationResolver"/> </property> <property name="pubSubDomain"> <value>false</value> </property> <property name="receiveTimeout"> <value>20000</value> </property> </bean> |
jmsQueueTemplate
bean 与 JMS 连接工厂和 JMS 目标解析器绑定在一起,用于解析 JMS 客户机通过 JNDI 提供的目标队列名。connectionFactory
属性指定了如何获得到 JMS 提供者的连接。在本例中,清单 2 显示了如何从 JNDI 检索连接工厂。
<!-- JMS Queue Connection Factory --> <bean id="internalJmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="jndiTemplate"/> </property> <property name="jndiName"> <value>MQ_JMS_MANAGER</value> </property> </bean> |
可以看到,JndiObjectFactoryBean
被绑定到 internalJmsQueueConnectionFactory
。JndiObjectFactoryBean
用 JndiTemplate
属性进行 JNDI 查询。Spring 将用 JndiTemplate
中指定的环境属性和初始上下文在 JNDI 中查询连接工厂。清单 3 显示了 JndiTemplate
配置 bean 的配置。
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial"> com.sun.jndi.fscontext.RefFSContextFactory </prop> <prop key="java.naming.provider.url"> file:/C:/JNDI-Directory </prop> </props> </property> </bean> |
以上配置进行 JNDI 查询时用 com.sun.jndi.fscontext.RefFSContextFactory
指定初始上下文工厂,用基于文件的 file:/C:/JNDI-Directory 作为提供者 URL。根据示例应用程序的意图,JNDI 访问会采用基于文件的 FSContext
版本(请参阅 参考资料)的配置把 MQ 队列绑定到 JNDI。
有了定义好的 JMS 模板,下一步就是把它绑定到示例应用程序中,然后就可以用它发送和接收消息了。
JMS 模板可以绑定到应用程序中,以发送和接收 JMS 消息。在清单 4 中可以看出我如何把 清单 1 中的 JMS 模板绑定到示例应用程序中。
<bean id="jmsSender" class="springexample.client.JMSSender"> <property name="jmsTemplate102"> <ref bean="jmsQueueTemplate"/> </property> </bean> <bean id="jmsReceiver" class="springexample.client.JMSReceiver"> <property name="jmsTemplate102"> <ref bean="jmsQueueTemplate"/> </property> </bean> |
可以看到,我把 jmsQueueTemplate
绑定到用来发送和接收消息的 JmsSender
应用程序 bean 和 JmsReceiver
bean。清单 5 显示了与 JMSSender
类有关的代码。
清单 5. 用 JmsTemplate 发送 JMS 消息的 JMSSender
public class JMSSender { private JmsTemplate102 jmsTemplate102; public JmsTemplate102 getJmsTemplate102() { return jmsTemplate102; } public void setJmsTemplate102(JmsTemplate102 jmsTemplate102) { this.jmsTemplate102 = jmsTemplate102; } public void sendMesage(){ jmsTemplate102.send("JMS_RequestResponseQueue", new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createTextMessage("This is a sample message"); } }); } |
JMSSender
类用 jmsTemplate102.send()
方法发送 JMS 消息。send()
方法的第一个参数是 JNDI 队列名,队列名指定了消息应当发送到哪里。(很快就会看到如何把 WebSphere MQ 的队列名绑定到 JNDI。)send()
方法的第二个参数是 MessageCreator
类。JmsTemplate
中的调用代码提供了 Session
类,这个类提供了一个创建 JMS 消息的回调接口。
下一步是用 JMS 的 Session
类创建一个简单的文本消息。在代码执行时,消息会传递给 WebSphere MQ 服务器的队列。清单 6 显示了使用 JmsTemplate
检索 JMS 消息的 JMSReceiver
应用程序 bean 的代码。
清单 6. 用 JmsTemplate 检索 JMS 消息的 JMSReceiver
public class JMSReceiver { private JmsTemplate102 jmsTemplate102; public JmsTemplate102 getJmsTemplate102() { return jmsTemplate102; } public void setJmsTemplate102(JmsTemplate102 jmsTemplate102) { this.jmsTemplate102 = jmsTemplate102; } public void processMessage(){ Message msg = jmsTemplate102.receive("JMS_RequestResponseQueue"); try{ TextMessage textMessage = (TextMessage) msg; if( msg!=null){ System.out.println(" Message Received -->" + textMessage.getText()); } }catch(Exception e){ e.printStackTrace(); } } } |
JMSReceiver
类用 jmsTemplate102.receive()
方法同步地接收 JMS 消息。receive()
方法指定 JNDI 队列名,并从中检索消息。JMSTemplate
类的 processMessage()
方法由接收 JMS 客户机调用。JSMTemplate
bean 的属性 receiveTimeout(列在 JMSTemplate
配置中)指定接收客户机同步地从队列中接收消息时要等候的时间。
现在应用程序的代码已完成!下一步就是配置 WebSphere MQ 队列并把它们绑定到 JNDI 对象。
在运行应用程序之前,需要设置 WebSphere MQ 的队列管理器和队列,并把它们绑定到 JNDI。如果喜欢的话,可以按照这部分的示例做:只需 下载 设置 WebSphere MQ 队列的批文件和应用程序的源代码和部署描述符即可。把 zip 文件解压到驱动器 C:。
设置队列
运行 C:\SpringSeriesPart4JMS\batch 文件夹中的 mqsetup.bat 文件。这个批文件要求在 path 环境变量中设置好 MQ 安装的 bin 文件夹(例如 C:\mqseries\bin)。运行了批文件之后,应当看到消息 “All valid MQSC commands were processed
”。要打开 MQ Explorer 并检查已经创建的队列管理器和队列,请选择 Start -> Programs -> IBM MQSeries -> MQSeriesExplorer。图 1 显示出示例应用程序 QueueManager
MQJMS.QManager
已经创建并正在运行。
图 1. WebSphere MQ 的 QueueManager 配置
请在应用程序屏幕左侧面板上点击 MQJMS.QManager
下的 Queues 文件夹。应当看到已经创建了一个队列 RequestResponseQueue
,如图 2 所示。
这就完成了队列的设置。
设置 JMS 和 JNDI 管理
在示例应用程序中,JNDI 的访问利用了可以从 JNDI 主页得到的基于文件的 FSContext
版本(请参阅 参考资料)。FSContext.jar 文件也包含在 WebSphere MQ 的 JMS 支持当中。请添加文件夹 \MQSeriesInstallable\MQSeries\Java\lib 和 \MQSeriesInstallable\MQSeries\Java\bin 到系统的 PATH 环境变量中。而且,请把 \MQSeriesInstallable\MQSeries\Java\lib 文件夹中的所有 jar 文件添加到系统的 CLASSPATH 环境变量中。还可以运行 C:\SpringSeriesPart4JMS\batch 文件夹中的 classpath.cmd 文件,它会设置必要的 path 和 CLASSPATH 变量。要做到这点,只需要修改 classpath.cmd 文件中的 MQ_JAVA_INSTALL_PATH
,把它指到 WebSphere MQ JMS 的安装目录。
接下来,修改 \MQSeriesInstallableDirectory\Java\bin 中的 JMSAdmin.config 配置文件,MQSeries JMS 管理程序用它指明应用程序要使用的上下文工厂和 JNDI 实现的地址。请取消以下行的注释:
INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory |
并注释掉其余两个 INITIAL_CONTEXT_FACTORY
变量。还要取消以下行的注释:
PROVIDER_URL=file:/C:/JNDI-Directory |
并注释掉其余两个 PROVIDER_URL
变量。
可以在 C:\SpringSeriesPart4JMS\batch 文件夹中发现参考的示例配置文件。
为了保存 JNDI 对象,请在驱动器 C: 上创建名为 JNDI-Directory 的目录。切换到 \MQSeriesInstallableDirectory\Java\bin 目录并运行 JMSAdmin 批文件,应当看到 InitCtx 变量。
逐个输入以下内容:
def qcf(MQ_JMS_MANAGER) qmgr(MQJMS.QManager) 按回车 def q(JMS_RequestResponseQueue) qmgr(MQJMS.QManager) queue(RequestResponseQueue) 按回车 |
现在已经把 WebSphere MQ 队列绑定到 JNDI 对象,作为应用程序客户可以通过 JNDI 查询对象。现在剩下的就是看代码的实际作用了!
要运行示例,请从 spring sourceforge download 下载 Spring 框架和它的所有依赖文件并解压,例如解压到 c:\。会创建文件夹 C:\spring-framework-1.2-rc2(或最新版本)。
要运行 Spring 应用程序,请把本文的源代码解压到任意文件夹,例如 c:\。会创建文件夹 SpringSeriesPart4JMS。就像前面提到过的,还需要安装 Apache Ant 和它的 Spring 依赖 jar 文件。请把 Spring 库 —— 即 spring.jar(在 C:\spring-framework-1.2-rc2\dist 中)和 commons-logging.jar(在 C:\spring-framework-1.2-rc2\lib\jakarta-commons 中)拷贝到 SpringSeriesPart4JMS\lib 文件夹。还要把所有的 jar 库从 \MQSeriesInstallableDirectory\Java\lib 目录拷贝到 SpringSeriesPart4JMS\lib 文件夹。其中包含 MQseries 和 JMS 的相关库。现在就拥有了构建的依赖集。
接下来,打开命令提示符,切换到 SpringProject4 目录,并在命令提示符下输入以下命令:
> ant -f build-jmssender.xml. |
这会构建并运行 SendMQSpringJMS
类,它会调用 JMSSender
类,发送消息到 WebSphere MQ RequestResponse
队列。SendMQSpringJMS
还会通过它的 ClassPathXmlApplicationContext
装入 spring 配置文件。一旦 bean 全部装载,就可以通过 Spring 的 ApplicationContext 的 getBean()
方法访问 JMSSender(请参阅清单 7)。
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "spring-mqseries-jms.xml" }); JMSSender jmsSender = (JMSSender) appContext.getBean("jmsSender"); |
消息传递到队列上之后,请运行 JMS 接收方客户机以检索消息。请打开命令提示符,切换到目录 SpringProject4,并输入:
> ant -f build-jmsreceiver.xml |
这会构建并运行 ReceiveMQSpringJMS
类,该类会调用 JMSReceiver
类,以从 WebSphere MQ 的 RequestResponse
队列接收文本消息。在控制台上会打印出以下消息:
Message Received --> This is a sample message. |
在 Spring 系列的最后这篇文章中,您学习了 Spring JMS 框架的基础。我首先介绍了示例应用程序的核心组件 —— Spring JMS 框架和 IBM 的 WebSphere MQ 5.3,然后介绍了如何用 Spring JMS 模板向 WebSphere MQ 队列发送消息和从中接收消息。虽然这个示例非常简单,但是可以把这里介绍的步骤应用到更复杂的应用程序。
我希望介绍 Spring 框架核心模块的这一系列对您有所帮助。请参阅 参考资料 学习更多有关 Spring 框架和 Spring JMS 的内容。