本示例分别对Queue/Topic的发送和接收做了详细的测试。
StaticInfo.java----存放JNDI和Context的常量
UserInfo.java----测试ObjectJMS用的Object PO类
JMSReceiveTest.java----控制JMS 接收的测试类,单例模式
JMSSendTest.java----控制JMS发送的测试类,单例模式。
QueueReceive.jave----接收Queue消息
TopicMsgReceive.java----接收topic消息
QueueSend.java----发送Queue消息
TopicMsgSend.java----发送Topic消息
运行测试类:
初学者可以自己写一个简单的jsp,加上四个button对下面四个方面进行调用就可以了。
JMSSendTest.getInstance().queueMsgTest()或者topicMsgTest()进行各种类型消息的发送
JMSReceiveTest.getInstance().queueMsgTest()或者topicMsgTest();控制消息接收的start/suspend.
在本文最后附上JMS的基本知识和编程模型
具体JMS在weblogic服务器配置请看:http://qidaoxp.iteye.com/admin/blogs/480058
1、StaticInfo.java
package report.test.jms.basic;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class StaticInfo {
// Defines the JNDI context factory.
public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
// Defines the JNDI provider url.
public final static String PROVIDER_URL = "t3://localhost:7001";
// Defines the JMS connection factory for the queue.
public final static String JMS_FACTORY = "javax.jms.QueueConnectionFactory";
// Defines the queue 用的是对应 QUEUE的JNDI名子
public final static String QUEUE = "testqueue";
// 定义主题发布者(JNDI名称)
public final static String TOPIC = "testtopic";
public final static String DURABLE_SUB ="MySub";
private static Context context=null;
// 返回应用服务器上下文
public static Context getContext() throws NamingException {
if (context == null) {
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
context = new InitialContext(env);
} catch (NamingException ex) {
ex.printStackTrace();
throw ex;
}
}
return context;
}
}
2、UserInfo.java
package report.test.jms.basic;
import java.io.Serializable;
public class UserInfo implements Serializable {
/**
* 测试Object类
*/
private static final long serialVersionUID = 1L;
private String name;
private String address;
private double age;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public double getAge() {
return age;
}
public void setAge(double age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3、JMSReceiveTest.java
package report.test.jms.receive;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import report.test.Test;
//JMS消息接收测试类
public class JMSReceiveTest {
private static final Log log = LogFactory.getLog(JMSReceiveTest.class);
private static boolean isReceiving = false;;
private static QueueReceive qr;
private static TopicMsgReceive tr;
private static JMSReceiveTest instance=null;
private void JMSReceiveTest(){
}
public static JMSReceiveTest getInstance(){
if(instance==null){
instance=new JMSReceiveTest();
}
return instance;
}
public void queueMsgTest() throws Exception {
if (isReceiving) {
qr.close();
qr = null;
System.out.println("Message receiver closed");
isReceiving = false;
} else {
System.out.println("Message start to receive");
qr = new QueueReceive();
qr.init();
isReceiving = true;
}
}
public void topicMsgTest() throws Exception {
if (isReceiving) {
tr.close();
tr = null;
System.out.println("Message receiver closed");
isReceiving = false;
} else {
System.out.println("Message start to receive");
tr = new TopicMsgReceive();
tr.init();
isReceiving = true;
}
}
}
4、JMSSendTest.java
package report.test.jms.send;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import report.test.Test;
import report.test.jms.receive.JMSReceiveTest;
public class JMSSendTest {
private static final Log log = LogFactory.getLog(JMSSendTest.class);
private static JMSSendTest instance=null;
private void JMSSendTest(){
}
public static JMSSendTest getInstance(){
if(instance==null){
instance=new JMSSendTest();
}
return instance;
}
private void queueMsgTest()throws Exception{
QueueSend qs = new QueueSend();
qs.init();
qs.send();
qs.close();
}
private void topicMsgTest()throws Exception{
TopicMsgSend ts = new TopicMsgSend();
ts.init();
ts.send();
ts.close();
}
}
5、QueueSend.java
package report.test.jms.send;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.ObjectMessage;
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.StreamMessage;
import javax.jms.TextMessage;
import static report.test.jms.basic.StaticInfo.*;
import report.test.jms.basic.StaticInfo;
import report.test.jms.basic.UserInfo;
public class QueueSend {
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;
private StreamMessage sm;
private BytesMessage bm;
private MapMessage mm;
private ObjectMessage om;
public void init()throws Exception{
initSender();
initMsg();
}
public void initSender() throws Exception {
qconFactory = (QueueConnectionFactory) getContext().lookup(
StaticInfo.JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) StaticInfo.getContext().lookup(StaticInfo.QUEUE);
qsender = qsession.createSender(queue);
qcon.start();
}
public void initMsg() throws Exception {
msg = qsession.createTextMessage();
sm = qsession.createStreamMessage();
bm = qsession.createBytesMessage();
mm = qsession.createMapMessage();
om = qsession.createObjectMessage();
msg.setText("TextMessage");
sm.writeString("StreamMessage");
sm.writeDouble(23.33);
String name = "BytesMessage";
byte[] block = name.getBytes();
bm.writeBytes(block);
mm.setString("name", "xmddl369");
UserInfo ui = new UserInfo();
ui.setName("xmddl369");
ui.setAddress("厦门");
ui.setAge(100);
om.setObject(ui);
}
public void send() throws Exception {
qsender.send(msg);
qsender.send(sm);
qsender.send(bm);
qsender.send(mm);
qsender.send(om);
}
public void close() throws JMSException {
qsender.close();
qsession.close();
qcon.close();
}
}
6、TopicMsgSend.java
package report.test.jms.send;
import javax.jms.BytesMessage;
import javax.jms.MapMessage;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import report.test.jms.basic.StaticInfo;
import report.test.jms.basic.UserInfo;
public class TopicMsgSend {
private TopicConnectionFactory tConFactory;
private TopicConnection tCon;
private TopicSession tSession;
private TopicPublisher tPublisher;
private Topic topic;
private TextMessage msg;
private StreamMessage sm;
private BytesMessage bm;
private MapMessage mm;
private ObjectMessage om;
public void init() throws Exception {
initPublisher();
initMsg();
}
public void initPublisher() throws Exception {
tConFactory = (TopicConnectionFactory) StaticInfo.getContext().lookup(
StaticInfo.JMS_FACTORY);
tCon = tConFactory.createTopicConnection();
tSession = tCon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
topic = (Topic) StaticInfo.getContext().lookup(StaticInfo.TOPIC);
tPublisher = tSession.createPublisher(topic);
tCon.start();
}
public void initMsg() throws Exception {
msg = tSession.createTextMessage();
sm = tSession.createStreamMessage();
bm = tSession.createBytesMessage();
mm = tSession.createMapMessage();
om = tSession.createObjectMessage();
msg.setText("TextMessage");
sm.writeString("StreamMessage");
sm.writeDouble(23.33);
String name = "BytesMessage";
byte[] block = name.getBytes();
bm.writeBytes(block);
mm.setString("name", "xmddl369");
UserInfo ui = new UserInfo();
ui.setName("xmddl369");
ui.setAddress("厦门");
ui.setAge(100);
om.setObject(ui);
}
public void send() throws Exception {
tPublisher.publish(msg);
tPublisher.publish(sm);
tPublisher.publish(bm);
tPublisher.publish(mm);
tPublisher.publish(om);
}
// 释放资源
public void close() throws Exception {
if (tPublisher != null) {
tPublisher.close();
}
if (tSession != null) {
tSession.close();
}
if (tCon != null) {
tCon.close();
}
System.out.println("Release Resource");
}
}
7、QueueReceive.jave
package report.test.jms.receive;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import javax.naming.NamingException;
import report.test.jms.basic.StaticInfo;
import report.test.jms.basic.UserInfo;
public class QueueReceive implements MessageListener {
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueReceiver qreceiver;
private Queue queue;
public void onMessage(Message msg) {
try {
if (msg instanceof TextMessage) {
System.out.println("This is a TextMsg:"
+ ((TextMessage) msg).getText());
} else if (msg instanceof StreamMessage) {
System.out.println("This is a StreamMsg:"
+ ((StreamMessage) msg).readString() + "\t"
+ ((StreamMessage) msg).readDouble());
} else if (msg instanceof BytesMessage) {
byte[] block = new byte[1024];
System.out.println("This is a BytesMsg:"
+ ((BytesMessage) msg).readBytes(block));
} else if (msg instanceof MapMessage) {
System.out.println("This is a MapMsg:"
+ ((MapMessage) msg).getString("name"));
} else if (msg instanceof ObjectMessage) {
UserInfo ui = (UserInfo) ((ObjectMessage) msg).getObject();
System.out.println("This is a ObjectMsg:" + ui.getName() + "\t"
+ ui.getAge());
}
} catch (JMSException jmse) {
jmse.printStackTrace();
}
}
public void init() throws NamingException, JMSException {
qconFactory = (QueueConnectionFactory) StaticInfo.getContext().lookup(
StaticInfo.JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) StaticInfo.getContext().lookup(StaticInfo.QUEUE);
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);
qcon.start();
}
public void close() throws JMSException {
qreceiver.close();
qsession.close();
qcon.close();
}
}
8、TopicMsgReceive.java
package report.test.jms.receive;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.StreamMessage;
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 javax.naming.NamingException;
import report.test.jms.basic.StaticInfo;
import report.test.jms.basic.UserInfo;
public class TopicMsgReceive implements MessageListener {
private TopicConnectionFactory tConFactory;
private TopicConnection tCon;
private TopicSession tSession;
private TopicSubscriber tSubscriber;
private Topic topic;
public void onMessage(Message msg) {
try {
if (msg instanceof TextMessage) {
System.out.println("This is a TextMsg:"
+ ((TextMessage) msg).getText());
} else if (msg instanceof StreamMessage) {
System.out.println("This is a StreamMsg:"
+ ((StreamMessage) msg).readString() + "\t"
+ ((StreamMessage) msg).readDouble());
} else if (msg instanceof BytesMessage) {
byte[] block = new byte[1024];
System.out.println("This is a BytesMsg:"
+ ((BytesMessage) msg).readBytes(block));
} else if (msg instanceof MapMessage) {
System.out.println("This is a MapMsg:"
+ ((MapMessage) msg).getString("name"));
} else if (msg instanceof ObjectMessage) {
UserInfo ui = (UserInfo) ((ObjectMessage) msg).getObject();
System.out.println("This is a ObjectMsg:" + ui.getName() + "\t"
+ ui.getAge());
}
} catch (JMSException jmse) {
jmse.printStackTrace();
}
}
public void init() throws NamingException, JMSException {
tConFactory = (TopicConnectionFactory) StaticInfo.getContext().lookup(
StaticInfo.JMS_FACTORY);
tCon = tConFactory.createTopicConnection();
tCon.setClientID("abcde");
tSession = tCon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
topic = (Topic) StaticInfo.getContext().lookup(StaticInfo.TOPIC);
tSubscriber = tSession.createDurableSubscriber(topic, StaticInfo.DURABLE_SUB);
tSubscriber.setMessageListener(this);
tCon.start();
}
public void close() throws JMSException {
if (tSubscriber != null) {
tSubscriber.close();
}
if (tSession != null) {
tSession.unsubscribe(StaticInfo.DURABLE_SUB);
tSession.close();
}
if (tCon != null) {
tCon.close();
}
System.out.println("Release Resource");
}
}
9、JMS介绍
JMS是java的消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输。JMS支持两种消息模型,Point-toPoint(P2P)和Publish/Subscribe(Pub/Sub),即点对点和发布订阅模型
运行的状态:当然,为了缓和这种严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息。
如果你希望发送的消息可以不被做任何处理、或者被一个消费者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型
消息的消费:在JMS中,消息的产生和消费是异步的。对于消息来说,JMS的消费者可以通过两种方式 来消费消息。
同步:订阅者或接受者调用receive方法来接受消息,receive方法在能够接收到消息之前(超时之前)将一直阻塞
异步:订阅者或接受者可以注册为一个消息监听器。当消息到达之后,系统自动调用监听器的onMessage方法
10、JMS编程模型
Connection Factory
创建Cooection对象的工厂,针对两种不同的JMS消息模型,分别有QueueConnectionFactory和TopicConnectionFactory两种。可以通过JNDI来查找ConnectionFactory的对象。
Destination
Destination的意思是消息生产者的消息发送目标或者说是消息消费者的消息来源,对于消息生产者来说,它的Destination是某个队列(Queue)或某个主题(Topic),对于消息消费者来说,它的Destination也是某个队列或主题(即消息来源)。所以,Destination实际上就是两种类型的对象——Queue,Topic。可以通过JNDI来查找Destination
Conneciton
Connection表示客户端和JMS系统之间建立的链接(对TCP/IP socket 的包装)。Connection可以产生一个或多个Session。跟ConnectionFactory一样,Connection也有两种QueueConnection和TopicConnection。
Session
Session使我们操作消息的接口,可以通过session创建生产者、消费者、消息等。Session提供了事务的功能。当我们需要使用session发送/接受多个消息时,可以将这些发送/接受动作放到一个事务中。同样,也分QueueSession和 TopicSession。
消息消费者
消息消费者由Session创建。用于接受被发送到Destination的消息,QueueReceiver和TopicSubscriber,可分别通过session的createReceiver(queue)或createSubscriber(topic)来创建,当然,也可以通过 session的createDurableSubscriber方法来创建持久化的订阅者。
MessageListener
消息监听器,如果注册了消息监听器,一旦消息到达,将自动调用监听器的onMessage方法。EJB中的MDB(Message Driver Bean)就是一种MessageListener。