JMS let’s you send messages containing for example a String, array of bytes or a serializable Java object, from one program to another. It doesn’t however use a direct connection from program A to program B, instead the message is sent to a JMS provider and put there in a Queue where it waits until the other program receives it.

MessageProducer is a Java program sending a JMS message to a Queue on the JMS Provider. MessageConsumer is another program which receives that message. These two programs can run on separate machines and all they have to know to communicate is the URL of the JMS Provider. The Provider can be for example a Java EE server, like JBoss orGlassfish. But don’t be afraid, you don’t need a full-blown JEE server to send a JMS message. In this article we will use ActiveMQ which is lightweight and easy to use.

First we need to download ActiveMQ. If you are using Linux, you can get it from this link. For Windows you can use this link. In case the links don’t work, you can find the files in ‘Downloads’ section on ActiveMQ’s webpage.

After the download, extract it to any directory and run the ‘activemq’ program from beneath the ‘{path-where-you-extracted-activemq}/bin’ directory:

user@user-laptop:~/activemq/apache-activemq-5.3.0/bin$ ./activemq

You should see a bunch of INFO messages appearing on the terminal:

...
INFO | ActiveMQ Web Demos at http://0.0.0.0:8161/demo
INFO | RESTful file access application at http://0.0.0.0:8161/fileserver
INFO | Started SelectChannelConnector@0.0.0.0:8161

Now the ActiveMQ server is up and running. You can close it any time by pressing Ctrl-C. ActiveMQ has a nice admin console, where you can see a lot of useful informations and change the settings: http://localhost:8161/admin/.

Now that we have a JMS provider running, let’s write our message producer and consumer programs. For that, you will need to put the ActiveMQ’s JAR file on the class path. The file you need is called (for version 5.3.0) ‘activemq-all-5.3.0.jar’ or something similar and is in the extracted ActiveMQ directory. In Eclipse you could click right mouse button on your project and choose Properties->Java Build Path->Libraries->Add External Library.

Here is the code of the program sending (producing) the messages:

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
import javax.jms.*;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; public classProducer {
// URL of the JMS server. DEFAULT_BROKER_URL will just mean
// that JMS server is on localhost
private static Stringurl = ActiveMQConnection.DEFAULT_BROKER_URL; // Name of the queue we will be sending messages to
private static Stringsubject = "TESTQUEUE"; public static void main(String[] args) throws JMSException {
// Getting JMS connection from the server and starting it
ConnectionFactoryconnectionFactory =
new ActiveMQConnectionFactory(url);
Connectionconnection = connectionFactory.createConnection();
connection.start(); // JMS messages are sent and received using a Session. We will
// create here a non-transactional session object. If you want
// to use transactions you should set the first parameter to 'true'
Sessionsession = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE); // Destination represents here our queue 'TESTQUEUE' on the
// JMS server. You don't have to do anything special on the
// server to create it, it will be created automatically.
Destinationdestination = session.createQueue(subject); // MessageProducer is used for sending messages (as opposed
// to MessageConsumer which is used for receiving them)
MessageProducerproducer = session.createProducer(destination); // We will send a small text message saying 'Hello' in Japanese
TextMessagemessage = session.createTextMessage("こんにちは"); // Here we are sending the message!
producer.send(message);
System.out.println("Sent message '" + message.getText() + "'"); connection.close();
}
}

There is a lot going on here. The Connection represents our connection with the JMS Provider – ActiveMQ. Be sure not to confuse it with SQL’s Connection. ‘Destination’ represents the Queue on the JMS Provider that we will be sending messages to. In our case, we will send it to Queue called ‘TESTQUEUE’ (it will be automatically created if it didn’t exist yet).

What you should note is that there is no mention of who will finally read the message. Actually, the Producer does not know where or who the consumer is! We are just sending messages into queue ‘TESTQUEUE’ and what happens from there to the sent messages is not of Producer’s interest any more.

The most interesting for us part in the above code is probably line 46 where we use function ‘.createTextMessage(”こんにちは”);’ to send a text message (in this case to our Japanese friend).

Now let’s see how to receive (consume) the sent message. Here is the code for the Consumer class:

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
import javax.jms.*;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; public classConsumer {
// URL of the JMS server
private static Stringurl = ActiveMQConnection.DEFAULT_BROKER_URL; // Name of the queue we will receive messages from
private static Stringsubject = "TESTQUEUE"; public static void main(String[] args) throws JMSException {
// Getting JMS connection from the server
ConnectionFactory connectionFactory
= new ActiveMQConnectionFactory(url);
Connectionconnection = connectionFactory.createConnection();
connection.start(); // Creating session for seding messages
Sessionsession = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE); // Getting the queue 'TESTQUEUE'
Destinationdestination = session.createQueue(subject); // MessageConsumer is used for receiving (consuming) messages
MessageConsumerconsumer = session.createConsumer(destination); // Here we receive the message.
// By default this call is blocking, which means it will wait
// for a message to arrive on the queue.
Messagemessage = consumer.receive(); // There are many types of Message and TextMessage
// is just one of them. Producer sent us a TextMessage
// so we must cast to it to get access to its .getText()
// method.
if (message instanceof TextMessage) {
TextMessagetextMessage = (TextMessage) message;
System.out.println("Received message '"
+ textMessage.getText() + "'");
}
connection.close();
}
}

As you see, it looks pretty similar to the Producer’s code before. Actually only the part starting from line 35 is substantially different. We produce there a MessageConsumerinstead of MessageReceiver and then use it’s .receive() method instead of .send(). You can see also an ugly cast from Message to TextMessage but there is nothing we could do about it, because .receive() method just returns interface Message (TextMessage interface extends Message) and there are no separate methods for receiving just TextMessage’s.

Compile now both programs remembering about adding ActiveMQ’s JAR file to the classpath. Before running them be also sure that the ActiveMQ’s instance is running (for example in a separate terminal). First run the Producer program:

2009/11/14 15:56:37 org.apache.activemq.
transport.failover.FailoverTransport doReconnect
情報: Successfully connected to tcp://localhost:61616
Sent message 'こんにちは'

If you see something similar to the output above (especially the ‘Sent message’ part) then it means that the message was successfully sent and is now inside the TESTQUEUE queue. You can enter the Queues section in the ActiveMQ’s admin consolehttp://localhost:8161/admin/queues.jsp and see that there is one message sitting in TESTQUEUE:

In order to receive that message run now the Consumer program:

2009/11/14 15:58:03 org.apache.activemq.
transport.failover.FailoverTransport doReconnect
情報: Successfully connected to tcp://localhost:61616
Received message 'こんにちは'

If you are getting above input (or something similar) everything went ok. The message was successfully received.

You are now probably thinking “Why would anybody want to do that??”. In fact, the code presented here to transfer just a small text message was pretty big, and you also needed an instance of ActiveMQ running, and dependencies in the classpath and all that…. Instead of using JMS we could use plain TCP/IP with few times less effort. So, what are good points of using JMS compared to simple TCP/IP or Java RMI? Here they are:

  • Communication using JMS is asynchronous. The producer just sends a message and goes on with his business. If you called a method using RMI you would have to wait until it returns, and there can be cases you just don’t want to lose all that time.
  • Take a look at how we run the example above. At the moment we run the Producer to send a message, there was yet no instance of Consumer running. The message was delivered at the moment the Consumer asked ActiveMQ for it. Now compare it to RMI. If we tried to send any request through RMI to a service that is not running yet, we would get a RemoteException. Using JMS let’s you send requests to services that may be currently unavailable. The message will be delivered as soon as the service starts.
  • JMS is a way of abstracting the process of sending messages. As you see in the examples above, we are using some custom Queue with name ‘TESTQUEUE’. The producer just knows it has to send to that queue and the consumer takes it from there. Thanks to that we can decouple the producer from the consumer. When a message gets into the queue, we can do a full bunch of stuff with it, like sending it to other queues, copying it, saving in a database, routing based on its contents and much more. here you can see some of the possibilities.

JMS is widely used as a System Integration solution in big, distributed systems like those of for example banks. There are many books dealing with this huge topic, for exampleEnterprise Integration Patterns. If you want to learn more about JMS itself you can do it for example on this JMS Tutorial on Sun’s webpage.

转载:http://www.javablogging.com/simple-guide-to-java-message-service-jms-using-activemq/

Simple guide to Java Message Service (JMS) using ActiveMQ的更多相关文章

  1. Java Message Service学习(一)

    一,背景 近期需要用到ActiveMQ接收Oozie执行作业之后的返回结果.Oozie作为消息的生产者,将消息发送给ActiveMQ,然后Client可以异步去ActiveMQ取消息. ActiveM ...

  2. Java Message Service

    en.wikipedia.org/wiki/Java_Message_Service Messaging is a form of loosely coupled distributed commun ...

  3. Jmeter 测试 JMS (Java Message Service)/ActiveMQ 性能

    前言 JMS介绍:JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...

  4. 认识 Java Message Service

    1. Java Message Service : 是一个消息服务的标准或者说是规范,允许应用程序组件基于JavaEE平台创建.发送.接收和读取消息. 实现Java 程序与MQ Server 之间互相 ...

  5. JMS Java消息服务(Java Message Service)

    JMS 在一些场景下RPC的同步方式可能不太适合业务逻辑的处理,并且这种方式在某些场景下会导致业务的紧耦合. 基于异步交互模型的JMS解决了RPC产生的紧耦合问题,它提供了一个可以通过网络访问的抽象消 ...

  6. 17) JMS: java Message Service(Java消息服务)

         JMS是一个标准,就像EJB,有很多开源的,商业的实现,ms技术对应的规范是jsr914,规范的实现称为jms provider,常见的实现有ActiveMQ.JBoss MQ.IBM We ...

  7. Spring的消息 Java Message Service (JMS)

     Spring有两种方法提供对EJB的支持: Spring能让你在Spring的配置文件里,把EJB作为Bean来声明.这样,把EJB引用置入到其他Bean的属性里就成为可能了,好像EJB就是另一个P ...

  8. Java消息队列--JMS概述

    1.什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...

  9. Java ActiveMQ 讲解(一)理解JMS 和 ActiveMQ基本使用(转)

    转自:http://www.cnblogs.com/luochengqiuse/p/4678020.html?utm_source=tuicool&utm_medium=referral 最近 ...

随机推荐

  1. decode-string(挺麻烦的)

    Java String作为参数传参是不会改变的,这个与常识的感觉不同. public String decodeString(String s) { s = ""; return ...

  2. bzoj2437

    会做jsoi那道game,这题就非常简单了吧 我们考虑空格的移动,显然,初始与空格位置距离为奇数的黑棋和距离为偶数的白棋并没有什么用, 空格不会移到那,我们直接把他们当作障碍,其他点我们当作可移动区域 ...

  3. 关于<img>标签与文字垂直居中

    要让左边的图片与后面的文字居中,如下效果 HTML代码: <img class="iconCls" alt="最新客户端" src="${bas ...

  4. LA 4119 (差分数列 多项式) Always an integer

    题意: 给出一个形如(P)/D的多项式,其中P是n的整系数多项式,D为整数. 问是否对于所有的正整数n,该多项式的值都是整数. 分析: 可以用数学归纳法证明,若P(n)是k次多项式,则P(n+1) - ...

  5. UVa 12169 (枚举+扩展欧几里得) Disgruntled Judge

    题意: 给出四个数T, a, b, x1,按公式生成序列 xi = (a*xi-1 + b) % 10001 (2 ≤ i ≤ 2T) 给出T和奇数项xi,输出偶数项xi 分析: 最简单的办法就是直接 ...

  6. hdu 4609 3-idiots(快速傅里叶FFT)

    比较裸的FFT(快速傅里叶变换),也是为了这道题而去学的,厚的白书上有简单提到,不过还是推荐看算法导论,讲的很详细. 代码的话是照着别人敲的,推荐:http://www.cnblogs.com/kua ...

  7. qt创建android项目后需要加入的参数

    默认用qtcreator5.2.0创建了一个quick项目,却报如下错误: error:cstdlib.h no such file or directory 解决方法: 打开项目文件untitled ...

  8. 最简单的视音频播放示例9:SDL2播放PCM

    本文记录SDL播放音频的技术.在这里使用的版本是SDL2.实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API.在Windows平台下,SDL封装了Direct3D这类的API ...

  9. 按钮点击WIN8 磁贴效果

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  10. Codeforces Round #361 (Div. 2) 套题

    A - Mike and Cellphone 问有没有多解,每个点按照给出的序列用向量法跑一遍 #include<cstdio> #include<cstring> #incl ...