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 接口)
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
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 方法把消息内容打印到控制台上。