EJB---->消息驱动bean--Queue 消息的发送与接收(PTP 消息传递模型)

QueueSender
import java.util.Properties;

import javax.jms.BytesMessage;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;

import com.foshanshop.ejb3.bean.Man;
/**
* 发送Queue消息
* @author lihuoming
*
*/
public class QueueSender {
    public static void main(String[] args) {
        QueueConnection conn = null;
        QueueSession session = null;
        try {
            Properties props = new Properties();
            props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            props.setProperty(Context.PROVIDER_URL, "localhost:1099");
            props.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
            InitialContext ctx = new InitialContext(props);
            
QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory");
            conn = factory.createQueueConnection();
            session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
            Destination destination = (Queue) ctx.lookup("queue/foshanshop");
            MessageProducer producer = session.createProducer(destination);
            
            //发送文本
            TextMessage msg = session.createTextMessage("佛山人您好,这是我的第一个消息驱动Bean");
            producer.send(msg);
            
            //发送Ojbect(对象必须实现序列化,否则等着出错吧)
            producer.send(session.createObjectMessage(new Man("大美女", "北京朝阳区和平里一号")));
            
            //发送MapMessage
            MapMessage mapmsg = session.createMapMessage();
            mapmsg.setObject("no1", "北京和平里一号");
            producer.send(mapmsg);
            
            //发送BytesMessage
            BytesMessage bmsg = session.createBytesMessage();
            bmsg.writeBytes("我是一个兵,来自老百姓".getBytes());
            producer.send(bmsg);            
            
            //发送StreamMessage
            StreamMessage smsg = session.createStreamMessage();
            smsg.writeString("巴巴运动网,http://www.babasport.com");
            producer.send(smsg);
            
        } catch (Exception e) {
         e.printStackTrace();
        }finally{
            try {
                session.close ();
                conn.close();
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
}
为了发送JMS 消息,我们需要一个指向JMS provider 的连接和一个消息目标地址。使用JMS 连接工厂可以获得
JMS provider 连接,而消息目标地址则由Queue/Topic 对象来表示。一旦拥有了JMS provider 连接对象,就可以用
它来创建Session 对象,Session 对象允许你进行消息发送和接收的操作。
一般发送消息有以下步骤:
(1) 得到一个JNDI 初始化上下文(Context);
例子对应代码:
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
props.setProperty(Context.PROVIDER_URL, "localhost:1099");
props.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
InitialContext ctx = new InitialContext(props);
EJB3.0 实例教程是《EJB3.0 入门经典》的精简版
版权所有:黎活明
(2) 根据上下文查找一个连接工厂TopicConnectFactory/ QueueConnectionFactory (有两种连接工厂,根据
topic/queue 来使用相应的类型)。该连接工厂是由JMS 提供的,不需我们自己创建,每个厂商都为它绑定了一个
全局JNDI,我们通过它的全局JNDI 便可获取它;
例子对应代码:
QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory");
(3) 从连接工厂得到一个连接(Connect 的类型有两种:TopicConnection/ QueueConnection);
例子对应代码:conn = factory.createQueueConnection();
(4) 通过连接来建立一个会话(Session);
例子对应代码:session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
这句代码意思是:建立不需要事务的并且能自动确认消息已接收的会话。
(5) 查找目的地(目的地的类型有两种:Topic/ Queue);
例子对应代码:Destination destination = (Queue) ctx.lookup("queue/foshanshop");
(6) 根据会话以及目的地来建立消息生产者MessageProducer (QueueSender 和TopicPublisher 都扩展自
MessageProducer 接口)
 
                                                                                                                                                                                        
PrintBean.java (Queue 消息的接收者)
Queue 消息的接收方,它是一个消息驱动Bean
package com.foshanshop.ejb3.impl;

import java.io.ByteArrayOutputStream;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.BytesMessage;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;

import com.foshanshop.ejb3.bean.Man;

@MessageDriven(activationConfig =
{
  @ActivationConfigProperty(propertyName="destinationType",
    propertyValue="javax.jms.Queue"),
  @ActivationConfigProperty(propertyName="destination",
    propertyValue="queue/foshanshop"),
  @ActivationConfigProperty(propertyName="acknowledgeMode", 
    propertyValue="Auto-acknowledge")
})
public class PrintBean implements MessageListener {

    public void onMessage(Message msg) {
        try {            
            if (msg instanceof TextMessage) {
                TextMessage tmsg = (TextMessage) msg;
                String content = tmsg.getText();
                System.out.println(content);
            }else if(msg instanceof ObjectMessage){
                ObjectMessage omsg = (ObjectMessage) msg;
                Man man = (Man) omsg.getObject();
                String content = man.getName()+ " 家住"+ man.getAddress();
                System.out.println(content);
            }else if(msg instanceof MapMessage){
                MapMessage map = (MapMessage) msg;
                String content = map.getString("no1");
                System.out.println(content);
            }else if(msg instanceof BytesMessage){
                BytesMessage bmsg = (BytesMessage) msg;
                ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[256]; 
                int length = 0; 
                while ((length = bmsg.readBytes(buffer)) != -1) { 
                      byteStream.write(buffer, 0, length); 
                }
                String content = new String(byteStream.toByteArray());
                byteStream.close(); 
                System.out.println(content);
            }else if(msg instanceof StreamMessage){
                StreamMessage smsg = (StreamMessage) msg;
                String content = smsg.readString();
                System.out.println(content);
            }
            
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}
上面通过@MessageDriven 注释指明这是一个消息驱动Bean,并使用@ActivationConfigProperty 注释配置消息的各种属性,其中destinationType 属性指定消息的类型为queue。destination 属性指定消息路径(Destination),消息驱动Bean 在发布时,如果路径(Destination)不存在,容器会自动创建,当容器关闭时该路径将被删除。运行本例子,当一个消息到达queue/foshanshop 队列,就会触发onMessage 方法,消息作为一个参数传入,在onMessage 方法里面得到消息体并调用print 方法把消息内容打印到控制台上。

posted on 2012-05-15 16:29  小强斋太  阅读(265)  评论(0编辑  收藏  举报

导航