jms queue,topic发送和接收

1 篇文章 0 订阅

jms queue,topic发送和接收
说明:这次博客内容共分为三部分,第一部分为背景说明以及环境创建,第二部分为jms queue发送和接收,三部分jms topic 的发送和接收
第一部分:背景
我们使用的消息服务的提供者是Tibco.Tibco也是jms标准制定参与者之一,它的API符合JMS的规范,所以看完本博客之后,如果使用其他厂商的JMS产品只需要替换一下实现类即可.
因为版权问题我在这里就不在上传Tibco软件了,有兴趣的的朋友可以去搜索一下(Tibco在国内使用的比较少,资源会少一些)
首先假设我们已经搭建好了jms服务(搭建服务也很简单,下载Tibco软件,安装Tibco软件就OK了),
1.使用Tibco 的EMS客户端登录EMS(我的Tibco装在了本机上,默认的端口号是7222,端口号可以在配置文件中修改)
输入命令:c localhost:7222
输入用户名:admin
输入密码:*
如图1.1所示:
注意:如果你的EMS是首次使用,默认用户名是admin也是最高权限的用户,没有密码(密码什么都不输入直接”Enter”)
修改密码可以使用命令:set password admin 123456;(命令解释:将用户admin的密码设置为123456;修改密码也可以使用这个命令)

    ![图1.1](https://img-blog.csdn.net/20160724105351904)

    图1.1说明:自上往下,第一个红线是tibco EMS 的客户端名称,第二个红线是输入的链接URL的三个是用户名,第四个是密码.输入正确之后显示的旧是图1.1的内容
2.创建用户
    创建用户
        create user TEST TEST password=TEST2016
        说明:创建用户名为TEST,用户说明为TEST,密码为TEST2016

        create user BW TEST password=BW2016
        说明:创建用户名为BW,用户说明为TEST,密码为BW2016

创建两个用户:TEST用户作为生产者;BW用户作为消费者

3.创建,队列以及赋权限:
    创建队列
        create queue TEST.OUT 
    说明:创建队列TEST.OUT

    队列设置
        setprop queue TEST.OUT secure,maxmsgs=30000,overflowPolicy=rejectIncoming;(一般队列的常见属性)
    说明:设置队列TEST.OUT的属性,最大消息数量,消息超过队列深度的处理等
    队列使用权
        grant queue TEST.OUT TEST all
        grant queue TEST.OUT BW all
    说明:把队列的所有使用权限赋给TEST和BW
4.创建topic,durable和赋权限
    创建topic
        create topic TEST.PUB.COMMONINFO
    topic权限
        grant topic TEST.PUB.COMMONINFO TEST subscribe,publish,durable,use_durable
    说明:把主题TEST.PUB.COMMONINFO的使用权限赋给TEST 
    创建Topic接收者 durable
    create durable TEST.PUB.COMMONINFO TEST.SUB.BW clientid=BW-TOPICSUB-TEST
    说明:创建主题的接收者durable: 
        durableName=TEST.SUB.BW 
        clientid=BW-TOPICSUB-TEST

    Topic权限
        grant topic TEST.PUB.COMMONINFO BW subscribe,use durable
EMS还有很多命令,你可以在客户端输入"help"自己查看
做完以上工作我们写代码需要的信息如下:
URL=tcp://localhost:7222
userName=TEST,  password=TEST2016
userName=BW,    password=BW2016
queueName=TEST.OUT
topicName=TEST.PUB.COMMONINFO
durableName=TEST.SUB.BW 
clientid=BW-TOPICSUB-TEST

啰嗦了半天终于准备就绪了;实际开发时作为外围系统以上的东西都不需要自己做,直接找消息服务器的同事们要就行了,他们来做这些工作.看了半天是不是觉得很坑大笑大笑大笑

第二部分:jms queue的发送和接收

在这里就不啰嗦了直接上代码,重要的地方看代码注释:
在多说一句:程序需导入要以下两个jar
jms.jar:jms的标准接口由Java提供
tibjms.jar:Tibco的实现,由Tibco提供,如果你的消息服务器是其他厂商提供,你需要替换这个jar
这两个jar在博客最后会提供下载链接

JMS queue发送

package com.jms.queue;

import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;

import com.tibco.tibjms.TibjmsQueueConnectionFactory;

public class TestQueueSender {
    public static void main(String[] args) {
        String serviceURL = "tcp://localhost:7222";
        String userName = "TEST";
        String password = "TEST2016";
        String queueName = "TEST.OUT";
        QueueConnection connection = null;
        QueueSession session = null;
        QueueSender sender = null;
        /*
         * 创建QueueConnectionFactory;
         * 我使用的是Tibco所以用TibjmsQueueConnectionFactory类,
         * 其他厂商的替换就OK了
         * 无论是哪个厂商的消息服务都视线了JMS的接口
         */
        QueueConnectionFactory factory= new TibjmsQueueConnectionFactory(serviceURL);;
        try {
            //创建connection
            connection = factory.createQueueConnection(userName,password);
            /*
             * 创建session
             * connection.createQueueSession(boolean,int)
             * 该方法有两个参数,第一个表示开启事务,
             * 当为true时,表示开启事务,此时会忽略第二个参数
             * 第二个参数为消息的确认方式有三个合法值
             * Session.AUTO_ACKNOWLEDGE 1:自动确认
             * Session.CLIENT_ACKNOWLEDGE 2:手动确认(自己调方法确认message.acknowledge())
             * Session.DUPS_OK_ACKNOWLEDGE 3
             */
            session = connection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
            //创建queue
            Queue queue = session.createQueue(queueName);
            //创建queue生产者
            sender = session.createSender(queue);
            /*
             * 创建text消息
             * 所有的消息都是Message的子类
             * Message没有消息体
             * 根据需求可以选择Message或其子类
             * 本示例选择TextMessage
             * Message提供了很多的set方法,但是并不都是让用户使用的,
             * 有些是服务提供者使用的,我们可以调用但并不起作用,具体可以查看Message API
             */
            TextMessage message = session.createTextMessage();
            //添加自定义的消息属性abc=123
            message.setStringProperty("abc", "123");
            //添加消息体
            message.setText("这是一个测试消息");
            //发送消息
            sender.send(message);
        } catch (JMSException e) {
            e.printStackTrace();
        }finally{
            //释放资源
            if(sender != null){
                try {
                    sender.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if(session != null){
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if(connection !=null){
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

jms Queue 接收
接收有两种方式:一种用while(true);另一种用MessageListener
下面是代码,因为代码的前半部分和queue发送时是一样的,我就不在谢注释了.

    public static void rv(){
        String serviceURL = "tcp://localhost:7222";
        String userName = "BW";
        String password = "BW2016";
        String queueName = "TEST.OUT";
        QueueConnection connection = null;
        QueueSession session = null;
        QueueReceiver rv = null;
        QueueConnectionFactory factory= new TibjmsQueueConnectionFactory(serviceURL);

        try {
            connection = factory.createQueueConnection(userName,password);
            session = connection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
            Queue queue = session.createQueue(queueName);
            //创建消息消费者
            rv = session.createReceiver(queue);
            //*************用Listener方式处理消息*******************//
            //以MessageListener的方式接收消息
            rv.setMessageListener(new MessageListener(){

                @Override
                public void onMessage(Message message) {
                    /*
                     * 此处可以对收到的消息进行处理
                     * 可以先判断message的实际类型(TextMessage或其他)
                     * 强制转换后根据业务需求自己处理
                     * 需要注意的是:当onMessage()方法执行完之前消息不会被消费掉
                     */
                    System.out.println(message);
                }
            });
            /*
             * 开始接收消息,只有执行了connection.start()方法,消息才被接收,
             * 否则消息有监听,但不能接收
             * 该方法一定要在rv.setMessageListener之后调用
             * 如果在之前调用,可能会有消息丢失
             */
            connection.start();
            //*************END*************//
    /*      
            //*************用循环的方式接收消息*************
            //接收消息
            connection.start();
            while(true){
                //当没有消息时receive()方法会阻塞线程
                Message message = rv.receive();
                //此处谢自己的消息处理逻辑
                System.out.println(message);
            }
            //*************END*************
    */

        } catch (JMSException e) {
            e.printStackTrace();
        }finally{
            //释放资源
            if(rv != null){
                try {
                    rv.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if(session != null){
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if(connection !=null){
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

注意:一个session只能创建一个监听,就算你创建多个QueueReceiver并添加多个MessageListener也只有一个在工作;
两种接收方式不能共存,你只能选择一种;

第三部分:topic的发送和接收
topic发送
topic的发送和queue的发送一样,只需类不同,代码中我就不在写注释了
代码:

    public static void topicPub(){
        String serviceURL = "tcp://localhost:7222";
        String userName = "TEST";
        String password = "TEST2016";
        String TopicName = "TEST.PUB.COMMONINFO";
        TopicConnection connection = null;
        TopicSession session = null;
        TopicPublisher pub = null;
        TopicConnectionFactory factory= new TibjmsTopicConnectionFactory(serviceURL);;
        try {
            connection = factory.createTopicConnection(userName,password);
            session = connection.createTopicSession(false,Session.AUTO_ACKNOWLEDGE);
            Topic Topic = session.createTopic(TopicName);
            pub = session.createPublisher(Topic);
            TextMessage message = session.createTextMessage();
            message.setStringProperty("abc", "123");
            message.setText("这是一个测试消息");
            pub.publish(message);
        } catch (JMSException e) {
            e.printStackTrace();
        }finally{
            //释放资源
            if(pub != null){
                try {
                    pub.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if(session != null){
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if(connection !=null){
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

topic订阅
这里使用的是durable的方式订阅topic,和queue一样也有两种方式,我这里只写其中的一种,

package com.exe;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;

import com.tibco.tibjms.TibjmsTopicConnectionFactory;

public class TibcoSUB {

    public static void main(String[] args)  {
        //服务器地址,多个地址用";"分割
        String url = "tcp://localhost:7222";

        //注册用户名
        String user = "BW";

        //注册用户密码
        String password = "BW2016";

        //tibco和durable信息
        String tibcoName = "TEST.PUB.COMMONINFO";
        String clientID = "BW-TOPICSUB-TEST";
        String durableName = "TEST.SUB.BW";
        //以上信息由ESB项目组提供

        //消息服务连接
        TopicConnection connection = null;

        //消息服务会话
        TopicSession session = null;

        //订阅
        TopicSubscriber sub = null;

        //消息对象
        Message message = null;
        try {
            //建立连接工厂
            TopicConnectionFactory tf = new TibjmsTopicConnectionFactory(url,clientID);
            //建立连接
            connection = tf.createTopicConnection(user, password);
            //建立会话
            session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
            //获取topic对象
            Topic topic = session.createTopic(tibcoName);
            sub = session.createDurableSubscriber(topic,durableName);
            //开始接收操作
            connection.start();
            while(true){
                message = sub.receive();
                if(message == null){
                    break;
                }
                //message有很多实现类,根据实际类型转换
                if(message instanceof BytesMessage){

                    System.out.println(message);

                }if(message instanceof TextMessage){

                    System.out.println(message);

                }

            }
        } catch (JMSException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }finally {
            if(sub != null){
                try {
                    sub.close();
                } catch (JMSException e) {
                    // TODO 自动生成的 catch 块
                    e.printStackTrace();
                }
            }
            if(session != null){
                try {
                    session.close();
                } catch (JMSException e) {
                    // TODO 自动生成的 catch 块
                    e.printStackTrace();
                }
            }
            if(connection != null){
                try {
                    connection.close();
                } catch (JMSException e) {
                    // TODO 自动生成的 catch 块
                    e.printStackTrace();
                }
            }
        }

    }

}

至此代码已经写完了,在下面会有jar下载地址,以后有时间可以给大家洗一洗ESB(企业服务总线)的开发,当然也是用的Tibco软件

tibco.jar下载
jms.jar下载

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值