一个简单的JMS客户端应用
J2EE应用客户端通常是用来访问安装在服务器端的J2EE组件。客户端是一个类文件,是一个简单的、独立的、运行在服务器外的程序。它描述了JMS应用必须完成的基本工作:
在J2EE应用中,以上工作全部或者部分由EJB容器完成。
- 配置运行J2EE客户端和应用的环境
- 同步接收消息的点对点(PTP)例子
- 使用监听器的订阅/发布(pub/sub)例子
每一个例子都包含两个程序:一个发送消息,另一个接收消息。可以在两个窗口中运行。
在运行例子前,必须确定运行环境已经配置好了。Table 1显示如何配置环境变量。Before you can run the examples, you need to make sure your environment is set appropriately. Table 1 shows how to set the environment variables needed to run J2EE applications on windows and unix platforms.
Table 1: Environment Settings for Compiling and Running J2EE Applications
Platform
Variable Name
Values
Windows
%Java_HOME%
Directory where the Java TM 2 SDK, Standard Edition, version 1.3.1 is installed
%J2EE_HOME%
Directory where the J2EE 1.3 SDK is installed, usuallyC:j2sdkee1.3
%CLASSPATH%
Include the following:
.;%J2EE_HOME%libj2ee.jar;%J2EE_HOME%liblocale
%PATH%
Include%J2EE_HOME%bin
UNIX
$JAVA_HOME
Directory where the Java 2 SDK, Standard Edition, version 1.3.1 is installed
$J2EE_HOME
Directory where the J2EE 1.3 SDK is installed, usually$HOME/j2sdkee1.3
$CLASSPATH
Include the following:
.:$J2EE_HOME/lib/j2ee.jar:$J2EE_HOME/lib/locale
$PATH
Include$J2EE_HOME/bin
2 一个简单的PTP例子
2.1 编写 PTP客户端程序
消息发送程序
SimpleQueueSender.java
完成以下任务:
- 用JNDI查找队列连接工厂(
QueueConnectionFactory)
和消息队列(Queue)- 创建连接(connection)和会话(session)
- 创建消息发送者(
QueueSender)
- 创建消息(
TextMessage)
- 发送消息到队列
- 发送控制消息表明消息末尾
消息接收程序
SimpleQueueReceiver.java
完成以下任务:
- 通过JNDI查找队列连接工厂(
QueueConnectionFactory
)和队列(queue)- 创建连接(connection )和会话(session)
- 创建消息接收者(
QueueReceiver
)- 开始连接,传送消息
- 从队列中接收消息,直至消息接受完毕
- 在finally代码块中关闭连接,关闭连接则自动关闭消息接收
有几种方式调用receive方法实现消息同步接收。如果没有定义参数或者参数为0,方法将一直处于封锁状态,直至消息到来
Message m = queueReceiver.receive();
Message m = queueReceiver.receive(0);对于一个简单的客户端程序,完全没有必要用这种方式。但如果不想让程序不必要的消耗系统资源,可以采取以下的一种方式:
- 调用receive(long timeout)方法,超时参数timeout大于0。receive(long timeout)根据指定的超时参数等待一个消息的到来,如果在这个时间内有可用的消息,则返回消息。如果超时后任没有可用的消息,则返回NULL
Message m = queueReceiver.receive(1); // 1 millisecond
- 调用reveiveNoWait()方法,如果有可用的消息到达,reveiveNoWait()方法将返回这个消息。
Message m = queueReceiver.receiveNoWait();
SimpleQueueReceiver
在无限循环 while loop中调用带超时参数的receive方法接收消息。调用receiveNoWait
方法也将得到同样的结果。 TheSimpleQueueReceiver
program uses an indefinitewhile
loop to receive messages, callingreceive
with a timeout argument. CallingreceiveNoWait
would have the same effect.2.2 编译PTP客户端
- 确定配置好环境变量,参见 Table 4.1, "Environment Settings for Compiling and Running J2EE Applications".
- 在DOS中编译以下两个源文件:
javac SimpleQueueSender.java
javac SimpleQueueReceiver.java2.3 运行JMS服务
如果使用J2EE 1.3 SDK,在DOS窗口中输入以下命令行,运行J2EE服务器:
j2ee -verbose一直等待,直至窗口中出现提示message
J2EE server startup complete
2.4 创建JMS管理对象Creating the JMS Administered objects
在编译客户端的窗口中,使用j2eeadmin命令行创建一个名为MyQueue的队列。最后一个参数表示创建的是哪一种消息目的。
j2eeadmin -addJmsDestination MyQueue queue
j2eeadmin -listJmsDestination
本例中使用由J2EE 1.3 SDK 提供的、缺省的队列连接工厂
QueueConnectionFactory
。你可以创建自己的连接工厂。2.5 运行PTP客户端
- 运行
SimpleQueueSender
程序,发送消息,首先要设置jms.properties的值
java -Djms.properties=%J2EE_HOME%configjms_client.properties SimpleQueueSender MyQueue 3
java -Djms.properties=$J2EE_HOME/config/jms_client.properties SimpleQueueSender MyQueue 3Queue name is MyQueue Sending message: This is message 1 Sending message: This is message 2 Sending message: This is message 3
- 在同一个窗口中,运行
SimpleQueueReceiver
程序,指定队列名称。命令行如下:java -Djms.properties=%J2EE_HOME%configjms_client.properties SimpleQueueReceiver MyQueue
java -Djms.properties=$J2EE_HOME/config/jms_client.properties SimpleQueueReceiver MyQueue
Queue name is MyQueue Reading message: This is message 1 Reading message: This is message 2 Reading message: This is message 3
- 如果按相反的顺序运行程序,先运行
SimpleQueueReceiver
,则先显示出队列名称,然后等待消息的到来。Now try running the programs in the opposite order. Start theSimpleQueueReceiver
program. It displays the queue name and then appears to hang, waiting for messages.- 在不同的窗口中,运行
SimpleQueueSender
,当发送消息,SimpleQueueReceiver
接收消息,然后退出。
2.6 删除队列Deleting the Queue
j2eeadmin -removeJmsDestination MyQueue
3 一个简单的发布/订阅消息样例
- 编写订阅/发布(pub/sub)客户端程序
- 编译订阅/发布(pub/sub)客户端
- 运行JMS提供者(一般指JMS服务器)
- 创建JMS管理对象
- 运行订阅/发布( pub/sub)客户端
- 删除主题,停止服务
3.1 编写Pub/Sub客户端程序
cpublisher.java" rel="nofollow">
SimpleTopicPublisher.java
完成以下任务:
- 用JNDI查找主题连接工厂(
TopicConnectionFactory
)
和消息主题(topic)- 创建连接( connection)和会话( session)
- 创建消息发布者(
TopicPublisher)
- 创建消息(
TextMessage)
- 发送消息到队列
- 发布消息给主题
- 在finally代码块中关闭连接( connection),关闭连接则自动关闭会话和消息发送
SimpleTopicSubscriber.java
完成以下任务:
- 通过JNDI查找主题连接工厂(
TopicConnectionFactory
)和主题(topic)- 创建连接( connection )和会话( session)
- 创建消息订阅者(
TopicSubscriber
)- 创建类
TextListener
实例,注册消息监听器- 开始连接,传送消息
- 监听消息主题,当用户输入'q'或者'Q'时停止监听
- 在finally代码块中关闭连接,关闭连接则自动关闭消息接收
消息监听器
TextListener.java
完成的任务如下:
3.2 编译Pub/Sub客户端Compiling the Pub/Sub Clients
按以下步骤编译pub/sub样例:
- 确定配置好环境变量,参见 Table 4.1, "Environment Settings for Compiling and Running J2EE Applications".
- 在DOS中编译以下源文件和监听器:
javac SimpleTopicPublisher.java javac SimpleTopicSubscriber.java javac TextListener.java
3.3 运行JMS服务器Starting the JMS Provider
如果使用J2EE 1.3 SDK,在DOS窗口中输入以下命令行,运行J2EE服务器:
j2ee -verbose一直等待,直至窗口中出现提示 message
J2EE server startup complete
3.4 创建JMS管理对象
在编译客户端的窗口中,使用j2eeadmin命令行创建一个名为
MyTopic
的主题。最后一个参数表示创建的是哪一种消息目的。j2eeadmin -addJmsDestination MyTopic topic
j2eeadmin -listJmsDestination
本例中使用由J2EE 1.3 SDK 提供的、缺省的队列连接工厂
TopicConnectionFactory
。你可以创建自己的连接工厂。3.5 运行pub/sub客户端
- 运行
SimpleTopicSubscriber
,定义主题名称,设置jms.properties的值。
java -Djms.properties=%J2EE_HOME%configjms_client.properties
SimpleTopicSubscriber MyTopic在UNIX系统下,输入以下命令:
java -Djms.properties=$J2EE_HOME/config/jms_client.properties
SimpleTopicSubscriber MyTopic显示下列信息,然后等待:
Topic name is MyTopic
To end program, enter Q or q, then- 在另一个DOS窗口,运行
SimpleTopicPublisher
,发布消息,命令行如下:java -Djms.properties=%J2EE_HOME%configjms_client.properties SimpleTopicPublisher MyTopic 3
java -Djms.properties=$J2EE_HOME/config/jms_client.properties SimpleTopicPublisher MyTopic 3
输出信息如下:
Topic name is MyTopic
Publishing message: This is message 1
Publishing message: This is message 2
Publishing message: This is message 3在另一个窗口,显示信息如下:
Reading message: This is message 1
Reading message: This is message 2
Reading message: This is message 3
3.6 删除主题,停止服务
j2eeadmin -removeJmsDestination MyTopic
j2ee -stopSimpleQueueSender.javaSimpleQueueSender.java
SimpleQueueSender.java
/*
*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the proprietary information of Sun
* Microsystems, Inc. Use is subject to license terms.
*
*/
/**
* The SimpleQueueSender class consists only of a main method,
* which sends several messages to a queue.
*
* Run this program in conjunction with SimpleQueueReceiver.
* Specify a queue name on the command line when you run the
* program. By default, the program sends one message. Specify
* a number after the queue name to send that number of messages.
*/
import javax.jms.*;
import javax.naming.*;
public class SimpleQueueSender {
/**
* Main method.
*
* @param args the queue used by the example and,
* optionally, the number of messages to send
*/
public static void main(String[] args) {
String queueName = null;
Context jndiContext = null;
QueueConnectionFactory queueConnectionFactory = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
Queue queue = null;
QueueSender queueSender = null;
TextMessage message = null;
final int NUM_MSGS;
if ( (args.length < 1) || (args.length > 2) ) {
System.out.println("Usage: java SimpleQueueSender " +
" []");
System.exit(1);
}
queueName = new String(args[0]);
System.out.println("Queue name is " + queueName);
if (args.length == 2){
NUM_MSGS = (new Integer(args[1])).intValue();
} else {
NUM_MSGS = 1;
}
/*
* Create a JNDI InitialContext object if none exists
* yet.
*/
try {
jndiContext = new InitialContext();
} catch (NamingException e) {
System.out.println("Could not create JNDI " +
"context: " + e.toString());
System.exit(1);
}
/*
* Look up connection factory and queue. If either does
* not exist, exit.
*/
try {
queueConnectionFactory = (QueueConnectionFactory)
jndiContext.lookup("QueueConnectionFactory");
queue = (Queue) jndiContext.lookup(queueName);
} catch (NamingException e) {
System.out.println("JNDI lookup failed: " +
e.toString());
System.exit(1);
}
/*
* Create connection.
* Create session from connection; false means session is
* not transacted.
* Create sender and text message.
* Send messages, varying text slightly.
* Send end-of-messages message.
* Finally, close connection.
*/
try {
queueConnection =
queueConnectionFactory.createQueueConnection();
queueSession =
queueConnection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
queueSender = queueSession.createSender(queue);
message = queueSession.createTextMessage();
for (int i = 0; i < NUM_MSGS; i++) {
message.setText("This is message " + (i + 1));
System.out.println("Sending message: " +
message.getText());
queueSender.send(message);
}
/*
* Send a non-text control message indicating end of
* messages.
*/
queueSender.send(queueSession.createMessage());
} catch (JMSException e) {
System.out.println("Exception occurred: " +
e.toString());
} finally {
if (queueConnection != null) {
try {
queueConnection.close();
} catch (JMSException e) {}
}
}
}
}
SimpleQueueReceive.java
/*
*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the proprietary information of Sun
* Microsystems, Inc. Use is subject to license terms.
*
*/
/**
* The SimpleQueueReceiver class consists only of a main method,
* which fetches one or more messages from a queue using
* synchronous message delivery. Run this program in conjunction
* with SimpleQueueSender. Specify a queue name on the command
* line when you run the program.
*/
import javax.jms.*;
import javax.naming.*;
public class SimpleQueueReceiver {
/**
* Main method.
*
* @param args the queue used by the example
*/
public static void main(String[] args) {
String queueName = null;
Context jndiContext = null;
QueueConnectionFactory queueConnectionFactory = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
Queue queue = null;
QueueReceiver queueReceiver = null;
TextMessage message = null;
/*
* Read queue name from command line and display it.
*/
if (args.length != 1) {
System.out.println("Usage: java " +
"SimpleQueueReceiver ");
System.exit(1);
}
queueName = new String(args[0]);
System.out.println("Queue name is " + queueName);
/*
* Create a JNDI InitialContext object if none exists
* yet.
*/
try {
jndiContext = new InitialContext();
} catch (NamingException e) {
System.out.println("Could not create JNDI " +
"context: " + e.toString());
System.exit(1);
}
/*
* Look up connection factory and queue. If either does
* not exist, exit.
*/
try {
queueConnectionFactory = (QueueConnectionFactory)
jndiContext.lookup("QueueConnectionFactory");
queue = (Queue) jndiContext.lookup(queueName);
} catch (NamingException e) {
System.out.println("JNDI lookup failed: " +
e.toString());
System.exit(1);
}
/*
* Create connection.
* Create session from connection; false means session is
* not transacted.
* Create receiver, then start message delivery.
* Receive all text messages from queue until
* a non-text message is received indicating end of
* message stream.
* Close connection.
*/
try {
queueConnection =
queueConnectionFactory.createQueueConnection();
queueSession =
queueConnection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
queueReceiver = queueSession.createReceiver(queue);
queueConnection.start();
while (true) {
Message m = queueReceiver.receive(1);
if (m != null) {
if (m instanceof TextMessage) {
message = (TextMessage) m;
System.out.println("Reading message: " +
message.getText());
} else {
break;
}
}
}
} catch (JMSException e) {
System.out.println("Exception occurred: " +
e.toString());
} finally {
if (queueConnection != null) {
try {
queueConnection.close();
} catch (JMSException e) {}
}
}
}
}
SimpleTopicPublisher.java
/*
*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the proprietary information of Sun
* Microsystems, Inc. Use is subject to license terms.
*
*/
/**
* The SimpleTopicPublisher class consists only of a main method,
* which publishes several messages to a topic.
*
* Run this program in conjunction with SimpleTopicSubscriber.
* Specify a topic name on the command line when you run the
* program. By default, the program sends one message.
* Specify a number after the topic name to send that number
* of messages.
*/
import javax.jms.*;
import javax.naming.*;
public class SimpleTopicPublisher {
/**
* Main method.
*
* @param args the topic used by the example and,
* optionally, the number of messages to send
*/
public static void main(String[] args) {
String topicName = null;
Context jndiContext = null;
TopicConnectionFactory topicConnectionFactory = null;
TopicConnection topicConnection = null;
TopicSession topicSession = null;
Topic topic = null;
TopicPublisher topicPublisher = null;
TextMessage message = null;
final int NUM_MSGS;
if ( (args.length < 1) || (args.length > 2) ) {
System.out.println("Usage: java " +
"SimpleTopicPublisher " +
"[]");
System.exit(1);
}
topicName = new String(args[0]);
System.out.println("Topic name is " + topicName);
if (args.length == 2){
NUM_MSGS = (new Integer(args[1])).intValue();
} else {
NUM_MSGS = 1;
}
/*
* Create a JNDI InitialContext object if none exists
* yet.
*/
try {
jndiContext = new InitialContext();
} catch (NamingException e) {
System.out.println("Could not create JNDI " +
"context: " + e.toString());
e.printStackTrace();
System.exit(1);
}
/*
* Look up connection factory and topic. If either does
* not exist, exit.
*/
try {
topicConnectionFactory = (TopicConnectionFactory)
jndiContext.lookup("TopicConnectionFactory");
topic = (Topic) jndiContext.lookup(topicName);
} catch (NamingException e) {
System.out.println("JNDI lookup failed: " +
e.toString());
e.printStackTrace();
System.exit(1);
}
/*
* Create connection.
* Create session from connection; false means session is
* not transacted.
* Create publisher and text message.
* Send messages, varying text slightly.
* Finally, close connection.
*/
try {
topicConnection =
topicConnectionFactory.createTopicConnection();
topicSession =
topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
topicPublisher = topicSession.createPublisher(topic);
message = topicSession.createTextMessage();
for (int i = 0; i < NUM_MSGS; i++) {
message.setText("This is message " + (i + 1));
System.out.println("Publishing message: " +
message.getText());
topicPublisher.publish(message);
}
} catch (JMSException e) {
System.out.println("Exception occurred: " +
e.toString());
} finally {
if (topicConnection != null) {
try {
topicConnection.close();
} catch (JMSException e) {}
}
}
}
}
SimpleTopicSubscriber.java
/*
*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the proprietary information of Sun
* Microsystems, Inc. Use is subject to license terms.
*
*/
/**
* The SimpleTopicSubscriber class consists only of a main
* method, which receives one or more messages from a topic using
* asynchronous message delivery. It uses the message listener
* TextListener. Run this program in conjunction with
* SimpleTopicPublisher.
*
* Specify a topic name on the command line when you run the
* program.
*
* To end the program, enter Q or q on the command line.
*/
import javax.jms.*;
import javax.naming.*;
import java.io.*;
public class SimpleTopicSubscriber {
/**
* Main method.
*
* @param args the topic used by the example
*/
public static void main(String[] args) {
String topicName = null;
Context jndiContext = null;
TopicConnectionFactory topicConnectionFactory = null;
TopicConnection topicConnection = null;
TopicSession topicSession = null;
Topic topic = null;
TopicSubscriber topicSubscriber = null;
TextListener topicListener = null;
TextMessage message = null;
InputStreamReader inputStreamReader = null;
char answer = '';
/*
* Read topic name from command line and display it.
*/
if (args.length != 1) {
System.out.println("Usage: java " +
"SimpleTopicSubscriber ");
System.exit(1);
}
topicName = new String(args[0]);
System.out.println("Topic name is " + topicName);
/*
* Create a JNDI InitialContext object if none exists
* yet.
*/
try {
jndiContext = new InitialContext();
} catch (NamingException e) {
System.out.println("Could not create JNDI " +
"context: " + e.toString());
e.printStackTrace();
System.exit(1);
}
/*
* Look up connection factory and topic. If either does
* not exist, exit.
*/
try {
topicConnectionFactory = (TopicConnectionFactory)
jndiContext.lookup("TopicConnectionFactory");
topic = (Topic) jndiContext.lookup(topicName);
} catch (NamingException e) {
System.out.println("JNDI lookup failed: " +
e.toString());
e.printStackTrace();
System.exit(1);
}
/*
* Create connection.
* Create session from connection; false means session is
* not transacted.
* Create subscriber.
* Register message listener (TextListener).
* Receive text messages from topic.
* When all messages have been received, enter Q to quit.
* Close connection.
*/
try {
topicConnection =
topicConnectionFactory.createTopicConnection();
topicSession =
topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
topicSubscriber =
topicSession.createSubscriber(topic);
topicListener = new TextListener();
topicSubscriber.setMessageListener(topicListener);
topicConnection.start();
System.out.println("To end program, enter Q or q, " +
"then ");
inputStreamReader = new InputStreamReader(System.in);
while (!((answer == 'q') || (answer == 'Q'))) {
try {
answer = (char) inputStreamReader.read();
} catch (IOException e) {
System.out.println("I/O exception: "
+ e.toString());
}
}
} catch (JMSException e) {
System.out.println("Exception occurred: " +
e.toString());
} finally {
if (topicConnection != null) {
try {
topicConnection.close();
} catch (JMSException e) {}
}
}
}
}
TextListener.java
/*
*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the proprietary information of Sun
* Microsystems, Inc. Use is subject to license terms.
*
*/
/**
* The TextListener class implements the MessageListener
* interface by defining an onMessage method that displays
* the contents of a TextMessage.
*
* This class acts as the listener for the SimpleTopicSubscriber
* class.
*/
import javax.jms.*;
public class TextListener implements MessageListener {
/**
* Casts the message to a TextMessage and displays its text.
*
* @param message the incoming message
*/
public void onMessage(Message message) {
TextMessage msg = null;
try {
if (message instanceof TextMessage) {
msg = (TextMessage) message;
System.out.println("Reading message: " +
msg.getText());
} else {
System.out.println("Message of wrong type: " +
message.getClass().getName());
}
} catch (JMSException e) {
System.out.println("JMSException in onMessage(): " +
e.toString());
} catch (Throwable t) {
System.out.println("Exception in onMessage():" +
t.getMessage());
}
}
}
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-991960/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10752043/viewspace-991960/