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. UVa 10883 (组合数 对数) Supermean

    在纸上演算一下就能看出答案是:sum{ C(n-1, i) * a[i] / 2^(n-1) | 0 ≤ i ≤ n-1 } 组合数可以通过递推计算:C(n, k) = C(n, k-1) * (n- ...

  2. bzoj1221: [HNOI2001] 软件开发

    挖坑.我的那种建图方式应该也是合理的.然后连样例都过不了.果断意识到应该为神奇建图法... #include<cstdio> #include<cstring> #includ ...

  3. 【.NET应用技巧】Asp.NET MVC 4 设置IIS下调试

    [环境] VS 2012  IIS7.5 [问题] MVC项目在创建时和APS.NET不同,不能够选择服务器类型,不能够直接把项目创建到IIS上. 如果在项目中直接更改属性,更换调试服务器类型,会报错 ...

  4. Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!

    最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web ...

  5. codevs 1088 神经网络

    bfs.语文题. #include<iostream> #include<cstdio> #include<cstring> #include<algorit ...

  6. XShell 屏幕锁定的恢复方法(Ctrl+Q)

    操作XShell过程中很多时间大家会习惯性的按Ctrl+S进行保存. Ctrl+S在XShell的作用是屏幕锁定,很多朋友会无法操作,会直接把窗口关闭. 解决方法: 快捷键 Ctrl+Q 即能完成解锁 ...

  7. Sql中判断“数据库"、"表"、"临时表"、"存储过程"和列”是否存在

    --判断数据库是否存在   IF EXISTS (SELECT * FROM MASTER..sysdatabases WHERE NAME = ''库名'')      PRINT ''exists ...

  8. 基于51,人体红外感应和RC522的门禁系统

    总结一下最近学的东西,这两天学的东西,rfid门卡系统终于弄出来来了,这个程序算现在写过的比较满意的程序,大家可以参考参考 主函数: #include<reg52.h> #include& ...

  9. css3 javascript 实现菜单按钮特效

    一个菜单按钮特效案例,简单的实现了动态效果. 代码效果预览地址: http://code.w3ctech.com/detail/2504 <div class="bar" i ...

  10. springmvc基础知识

    springmvc框架,类似于struts,主要用于MVC的控制层 spring的简单配置(非注解):  spring-mvc.xml文件(springMVC框架的基本文件) web.xml文件 ja ...