JMS 实践

                            JMS实践-----------------浅谈JMSMDB

在做JMS程序之前找了一些资源,总觉得不是很合适,要么讲的很理论化----理论描述过多,实际介绍不足,要么就是全是动手缺少理论的深入。通过这几天的研究和动手,对JMSMDB有了一个比较深刻的理解咯。

先从JMS程序谈起,首先,JMSJDBC一样,是sun推出的一组API的集合,不同的厂商去实现这些接口。JMS的类型:queuetopic,这些的区别,也不再废话多说。

JMS的消息分为两种,一个是消息头,一个消息体。

一个JMS程序包括以下部分。一个是支持JMS的服务器,一个JMS的生产者,即向服务器发送消息,这个没有任何要求,可以是任何程序,包括ServletJSP,或者Java Application

发送JMS消息,跟写通过JDBC向数据库做操作一样。首先要查找数据源,建立数据库连接。JMS程序也是一样。不过它是基于JNDI的方式,比如假如你想往JBOSS服务器发送JMS消息,你要这样像建立数据源一样,准备一个jndi.properties文件:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory-----基本不需要改变,设置在jboss/server/default/config/jndi下面。

java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces---同上

java.naming.provider.url=localhost:1099//localhost是服务器的地址,这里默认为本地

 

你可以把这个文件放到你的classpath下面,然后通过API去获得里面的内容,获得JNDIConnection

MessageProducer messageProducer =null;

             QueueSession session = null;

             MessageObject msgobj= null;

             Properties prop = new Properties();

             initialProperties(prop);

             InitialContext ctx = new InitialContext(prop);

             QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory");

             Queue queue = (Queue) ctx.lookup("queue/haha");

                //这里lookup的内容在queue-example-service.xml有定义jndi

//这里的内容是一个JNDI上一个资源,以后可以把一个MDB制定为queue/haha,

//假如没有MDB,则可以自己在Jboss建立一个资源,我是这样建立一个资源的。

//打开你的C:/TOOLS/jboss-4.2.2.GA/server/default/deploy/jms,找到jbossmq-destination-service.xml文件,在最后面加上

<mbean code="org.jboss.mq.server.jmx.Queue"

        name="jboss.mq.destination:service=Queue,name=haha">

    <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>

  </mbean>

然后,就能在jboss里看到这个资源了。,假如是mdb的话,就不需要修改这个文件,而只需要你建立一个jboss.xml文件,把你的mdb对象和Queue绑定一下。jboss会自动建立新的Queue对象的

             cnn = factory.createQueueConnection();

             session = cnn.createQueueSession(false,//不需要事务

             QueueSession.AUTO_ACKNOWLEDGE);//自动接收消息

             ObjectMessage objmsg = session.createObjectMessage();

             //objmsg.setObject((Serializable)msgobj);

            /* TextMessage msg = session.createTextMessage("This is the Message!");*/

             //sender = session.createSender(queue);

             messageProducer =session.createProducer(queue);

             List data =new ArrayList();

             //sender.send(msg);

             for(int i =0;i<10;i++){

                    msgobj = new MessageObject();

                    msgobj.setId("id is "+String.valueOf(i));

                    msgobj.setContent("How are you !This is message "+i);

                    //sender.send(objmsg);

                    System.out.println("Sending Message......+......"+i);

                    

                    data.add(msgobj);

             }

             objmsg.setObject((Serializable) data);

             messageProducer.send(objmsg);

             System.out.println("Message sent successfully to remote queue.");

 

这样,只要把jbossall-client.jar导入到你的工程的classpath下就可以运行这个程序。这个程序运行成功后,你可以看到刚才建立的MQ类型的队列里的消息

点击以后,看看该资源有那些消息

 

消息内容部分,

 

要想处理该消息,有两种办法,一个是编写一个简单的消费程序----消费程序可以任何形式的,JSPservletBean,但是还需要编写一个MessageListener对象,然后set到这个消费者程序里,这样就能处理JMS消息了

首先展示的MessageListener程序:

Public class MyListneer implements javax.jms.listener{

 

 

public void onMessage(Message recvMsg)

   {

       try {

      System.out.println("----------------");

      System.out.println("Received message");

      if(recvMsg instanceof ObjectMessage){

             ObjectMessage msg2 = (ObjectMessage)recvMsg;

               Object obj =msg2.getObject();

               List data =(List)obj;

               int j =data.size();

               for(int i =0;i<j;i++){

                      MessageObject messageObject =(MessageObject) data.get(i);

                      System.out.println("MessageObject message content: "+messageObject.getId());

               }

             /*List list =(List)obj;

             for(Iterator iterator =list.iterator();iterator.hasNext();){

                    MessageObject mo =(MessageObject)iterator.next();

                    String cont =mo.getContent();

                    System.out.println(cont);

                    

             }*/

      }

      System.out.print("OutputMessage: "+recvMsg);

     

      System.out.println("----------------");

     

              //recvMsg.clearBody();

       } catch (JMSException e) {

              // TODO Auto-generated catch block

              e.printStackTrace();

              mdc.setRollbackOnly();

       }

   }

 

}

然后是消费者程序:

public class JMSReceiver {

       /**

        * @param args

        */

       public static void main(String[] args) {

              try{

              QueueConnection cnn = null;

             QueueSession session = null;

             TextMessage msg = null;

             FileInputStream  in = new FileInputStream("d:/test/jndi.properties");

             Properties prop = new Properties();

             prop.load(in);     

             InitialContext ctx = new InitialContext(prop);

             Queue queue = (Queue) ctx.lookup("queue/haha");

                //这里lookup的内容在queue-example-service.xml有定义jndi

             System.out.println(queue);

             QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory");

             cnn = factory.createQueueConnection();

             session = cnn.createQueueSession(false,//不需要事务

             QueueSession.AUTO_ACKNOWLEDGE);//自动接收消息

             QueueReceiver receiver = session.createReceiver(queue);

             receiver.setMessageListener(new MyListener());

             cnn.start();       

              }catch(Exception e){

                     e.printStackTrace();

              }

 

       }

}

当这个侦听程序被setter到消费者程序里以后,改侦听程序是一直在运行的,当再有新消息来的时候,会一直在处理。

 

这里需要特别说明的MDB程序,其实MDB本身是JMS体系的一部分,要不然sun推出这个特殊的EJB干吗?

编写MDB程序,其实就是在刚才的那个侦听程序上再多实现一个接口javax.ejb.MessageDrivenBean,这样就不需要再编写一个消费者程序去主动拿server上的消息了-----而是当服务器上有了消息以后,就会自动调用改MDBonMessage方法----前提是你的MDB必须事先注册到server(注意必须是EJB的发布方式,要有ejb-jar.xml,可能还需要一个jboss.xml文件,把你的MDB注册在里面。

第一个ejb-jar.xml:

<message-driven id="MessageDriven_1">

         <description><![CDATA[<!-- begin-xdoclet-definition -->]]></description>

 

         <ejb-name>ExampleMDB</ejb-name>

 

         <ejb-class>mdb.test.ExampleMDB</ejb-class>

 

         <messaging-type>javax.jms.MessageListener</messaging-type>

         <transaction-type>Bean</transaction-type>

         <message-destination-type>javax.jms.Queue</message-destination-type>

         <activation-config>

           <activation-config-property>

             <activation-config-property-name>destinationType</activation-config-property-name>

             <activation-config-property-value>javax.jms.Queue</activation-config-property-value>

           </activation-config-property>

           <activation-config-property>

             <activation-config-property-name>acknowledgeMode</activation-config-property-name>

             <activation-config-property-value>Auto-acknowledge</activation-config-property-value>

           </activation-config-property>

         </activation-config>

 

      </message-driven>

 

Jboss.xml:

<?xml version="1.0" encoding="UTF-8"?>

<jboss>

    <enterprise-beans>

       <message-driven>

           <ejb-name>ExampleMDB</ejb-name>

           <destination-jndi-name>queue/exampleMDB</destination-jndi-name>

       </message-driven>

      

    </enterprise-beans> 

</jboss>

 

这样就可以了。

再说部署,假如没有MDB程序,必须在jboss-destination-server.xml文件里添加一个queue或者topic的对象,比如说queue/haha, 而假如采用了MDB,择需要采取灵活的方式,在jboss里绑定一个MDBQueue对象上。

<?xml version="1.0" encoding="UTF-8"?>

<jboss>

    <enterprise-beans>

       <message-driven>

           <ejb-name>ExampleMDB</ejb-name>

           <destination-jndi-name>queue/exampleMDB</destination-jndi-name>

       </message-driven>

      

    </enterprise-beans> 

</jboss>

那么在JBosss启动的时候,可以看到由jboss新建好的这个 queue/exampleMDB”.客户端程序再连接这个建好的Queue

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值