前言

之所以使用JNDI 是出于通用性考虑,该例子使用JMS规范提供的通用接口,没有使用具体JMS提供者的接口,这样可以保证我们编写的程序适用于任何一种JMS实现(ActiveMQ、HornetQ等)。

什么是JNDI:JNDI(Java Naming and Directory Interface)是一个标准规范,类似于JDBC,JMS等规范,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口。J2EE 规范要求所有 J2EE 容器都要提供 JNDI 规范的实现,因此Tomcat就实现了JNDI 规范。

PTP(Point to point)消息模式(JMS的点对点消息传送)

1、使用Tomcat配置JNDI

找到Tomcat安装路径下的conf文件夹,打开context.xml,添加如下配置:

<Resource name="queue/connectionFactory"
auth="Container"
type="org.apache.activemq.ActiveMQConnectionFactory"
description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
brokerURL="tcp://localhost:61616"
brokerName="LocalActiveMQBroker" /> <Resource name="queue/queue0"
auth="Container"
type="org.apache.activemq.command.ActiveMQQueue"
description="My Queue"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
physicalName="TomcatQueue" />

2、启动ActiveMQ

3、编写一个Web工程

Eclipse上新建web工程,添加ActiveMQ依赖的jar包,然后开始编写两个Servlet,一个用于生产消息,另一个用于消费消息,如下代码:

消息生产者Servlet

import java.io.IOException;
import java.io.PrintWriter; import javax.jms.DeliveryMode;
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.TextMessage;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class JMSTest
*/
@WebServlet("/Send")
public class Send extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public Send() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter(); try {
// get the initial context
InitialContext context = new InitialContext(); // lookup the queue object
Queue queue = (Queue) context.lookup("java:comp/env/queue/queue0"); // lookup the queue connection factory
QueueConnectionFactory conFactory = (QueueConnectionFactory) context
.lookup("java:comp/env/queue/connectionFactory"); // create a queue connection
QueueConnection queConn = conFactory.createQueueConnection(); // create a queue session
QueueSession queSession = queConn.createQueueSession(false,
Session.DUPS_OK_ACKNOWLEDGE); // create a queue sender
QueueSender queSender = queSession.createSender(queue);
queSender.setDeliveryMode(DeliveryMode.NON_PERSISTENT); // create a simple message to say "Hello World"
TextMessage message = queSession.createTextMessage("Hello World"); // send the message
queSender.send(message); // print what we did
out.write("Message Sent: " + message.getText()); // close the queue connection
queConn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

消息消费者Servlet

import java.io.IOException;
import java.io.PrintWriter; 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.TextMessage;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class Receive
*/
@WebServlet("/Receive")
public class Receive extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public Receive() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter(); try {
// get the initial context
InitialContext context = new InitialContext(); // lookup the queue object
Queue queue = (Queue) context.lookup("java:comp/env/queue/queue0"); // lookup the queue connection factory
QueueConnectionFactory conFactory = (QueueConnectionFactory) context
.lookup("java:comp/env/queue/connectionFactory"); // create a queue connection
QueueConnection queConn = conFactory.createQueueConnection(); // create a queue session
QueueSession queSession = queConn.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE); // create a queue receiver
QueueReceiver queReceiver = queSession.createReceiver(queue); // start the connection
queConn.start(); // receive a message
TextMessage message = (TextMessage) queReceiver.receive(); // print the message
out.write("Message Received: " + message.getText()); // close the queue connection
queConn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

4、验证结果

在Tomcat里运行该Web工程,执行消息生产者Servlet,返回消息发送成功标志,同时我们可以在http://localhost:8161/admin/queues.jsp查看到该消息,如下图所示

继续执行消息消费者Servlet,返回消息接收成功标志,同时我们可以打开http://localhost:8161/admin/queues.jsp页面,发现刚才的消息已经不见了,如下图所示

Pub/Sub消息模式(JMS发布/订阅消息传送

1、在Tomcat中配置JNDI

配置连接工厂和话题:

<Resource name="topic/connectionFactory" auth="Container"
type="org.apache.activemq.ActiveMQConnectionFactory" description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
brokerURL="failover:(tcp://localhost:61616)?initialReconnectDelay=100&amp;maxReconnectAttempts=5"
brokerName="LocalActiveMQBroker" useEmbeddedBroker="false" /> <Resource name="topic/topic0"
auth="Container"
type="org.apache.activemq.command.ActiveMQTopic" description="My Topic" factory="org.apache.activemq.jndi.JNDIReferenceFactory"
physicalName="TestTopic" />

2、启动ActiveMQ

3、在Web工厂中编写代码

新建一个发布者Servlet:

package pubSub;

import java.io.IOException;
import java.io.PrintWriter; import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.jms.Topic;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.TopicPublisher;
import javax.jms.DeliveryMode;
import javax.jms.TopicSession;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory; /**
* Servlet implementation class JMSTest
*/
@WebServlet("/Publish")
public class Publisher extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public Publisher() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter(); try {
// get the initial context
InitialContext ctx = new InitialContext(); // lookup the topic object
Topic topic = (Topic) ctx.lookup("java:comp/env/topic/topic0"); // lookup the topic connection factory
TopicConnectionFactory connFactory = (TopicConnectionFactory) ctx
.lookup("java:comp/env/topic/connectionFactory"); // create a topic connection
TopicConnection topicConn = connFactory.createTopicConnection(); // create a topic session
TopicSession topicSession = topicConn.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE); // create a topic publisher
TopicPublisher topicPublisher = topicSession.createPublisher(topic);
topicPublisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT); // create the "Hello World" message
TextMessage message = topicSession.createTextMessage();
message.setText("Hello World"); // publish the messages
topicPublisher.publish(message); // print what we did
out.write("Message published: " + message.getText()); // close the topic connection
topicConn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

新建一个订阅者Servlet

package pubSub;

import java.io.IOException;
import java.io.PrintWriter; import javax.jms.Session;
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.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class Receive
*/
@WebServlet("/Subscribe")
public class Subscriber extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public Subscriber() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter(); try {
// get the initial context
InitialContext ctx = new InitialContext(); // lookup the topic object
Topic topic = (Topic) ctx.lookup("java:comp/env/topic/topic0"); // lookup the topic connection factory
TopicConnectionFactory connFactory = (TopicConnectionFactory) ctx
.lookup("java:comp/env/topic/connectionFactory"); // create a topic connection
TopicConnection topicConn = connFactory.createTopicConnection(); // create a topic session
TopicSession topicSession = topicConn.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE); // create a topic subscriber
TopicSubscriber topicSubscriber = topicSession
.createSubscriber(topic); // start the connection
topicConn.start(); // receive the message
TextMessage message = (TextMessage) topicSubscriber.receive(); // print the message
out.write("Message received: " + message.getText()); // close the topic connection
topicConn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

4、验证结果

运行Web工程,分别打开多个标签访问订阅servlet,然后访问发布servlet,结果如下:

在订阅者订阅消息的时候,一开始没接收到消息,一旦发布者发布消息后,订阅者马上收到消息。

使用Tomcat、JNDI与ActiveMQ实现JMS消息通信服务的更多相关文章

  1. 使用ActiveMQ实现JMS消息通信服务

    PTP(点对点的消息模型) 在点对点模型中,相当于两个人打电话,两个人独享一条通信线路.一方发送消息,一方接收消息. 在p2p的模型中,双方通过队列交流,一个队列只有一个生产者和一个消费者. 1.建立 ...

  2. JMS消息通信服务

    什么是Java消息服务 Java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建.发送.读取消息等,用于支持JAVA应用程序开发.在J2EE中 ...

  3. ActiveMQ的JMS消息可靠机制

    JMS消息可靠机制 ActiveMQ消息签收机制: 客戶端成功接收一条消息的标志是一条消息被签收,成功应答. 消息的签收情形分两种: 1.带事务的session 如果session带有事务,并且事务成 ...

  4. vscode源码分析【七】主进程启动消息通信服务

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...

  5. activemq和jms是种什么关系

    JMS是一个用于提供消息服务的技术规范,它制定了在整个消息服务提供过程中的所有数据结构和交互流程. 而activemq则是消息队列服务,是面向消息中间件(MOM)的最终实现,是真正的服务提供者. jm ...

  6. 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    一种分类是推和拉 . 还有一种分类是 Queue 和 Pub/Sub . 先看的这一篇:http://blog.csdn.net/heyutao007/article/details/50131089 ...

  7. 消息中间件--ActiveMQ&JMS消息服务

    ### 消息中间件 ### ---------- **消息中间件** 1. 消息中间件的概述 2. 消息中间件的应用场景 * 异步处理 * 应用解耦 * 流量削峰 * 消息通信   --------- ...

  8. ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...

  9. Java消息队列ActiveMQ (一)--JMS基本概念

    摘要:The Java Message Service (JMS) API is a messaging standard that allows application components bas ...

随机推荐

  1. [shell]管道连接的命令判断返回值

    场景: 在bash执行管道连接的命令,需要获取到各个命令的返回值用于判断 在脚本中我们可能需要将执行结果打印到屏幕,同时保存在文件中供后面分析用,写出如下的命令 command 2>&1 ...

  2. codefroces Round #201.B--Fixed Points

    B. Fixed Points time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  3. phpfor函数和foreach函数

    PHP for 循环 PHP While 循环 PHP 函数 PHP for 循环执行代码块指定的次数. PHP for 循环 如果您已经提前确定脚本运行的次数,可以使用 for 循环. 语法 for ...

  4. 分布式-网络通信-线程(socket)

    package OIO; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; i ...

  5. Redis Cluster with SpringBoot

    前提: 按照 https://www.cnblogs.com/luffystory/p/12081074.html 配置好Redis Cluster in Ubuntu 按照如下结构搭建项目结构: P ...

  6. Ubuntu 16.04配置SSL免费证书

    主要参考地址为:https://blog.csdn.net/setoy/article/details/78441613 本篇主要以Apache这个web服务器来讲解,所以前提必须要安装好apache ...

  7. vue-微信浏览器左上角返回按钮拦截

    [需求] 在微信公众号开发中,有时需要对浏览器左上角返回按钮进行拦截处理相关的页面逻辑,而并不是让页面直接返回上一页,之前在这个细节点上的一直实现得不是很好.但看到京东购物公众号上的效果却实现得非常好 ...

  8. Android内存Activity泄露:Handler与Threads

    Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用所指向,则该对象会在被 ...

  9. JAVA初级面试题,附个人理解答案

    一,面向对象的特征:1.抽象 包括数据抽象跟行为抽象,将对象共同的特征取出形成一个类2.继承 被继承类为基类/超类,继承类为子类/派生类3.封装 多次使用道德数据或方法,封装成类,方便多次重复调用4. ...

  10. 基于java config的springSecurity--session并发控制

    原作地址:http://blog.csdn.net/xiejx618/article/details/42892951 参考资料:spring-security-reference.pdf的Sessi ...