前言

之所以使用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. JavaScript 的基本概念( ES5 )

    语法 区分大小写 标识符 第一个字符必须是一个字母,下划线或者一个美元符( $ ).其他规则无论,最好按照通用的驼峰大小写. 注释 // 单行注释 /* 多行注释 */ 严格模式 在顶部添加如下代码 ...

  2. sqli-labs(41) and 两php函数的讲解

    0X01 构造闭合 发现 不需要闭合 直接构造 id=- union ,database(), 成功 注入 0X02 堆叠注入同道理 一样的 这里我们来了解一下这个函数 mysqli_multi_qu ...

  3. [CSP-S模拟测试]:小W的魔术(数学 or 找规律)

    题目传送门(内部题130) 输入格式 第一行一个整数$n$,表示字符串的长度. 第二行一个只包含小写字母的字符串$s$. 输出格式 一行一个整数表示答案对$998244353$取模后的结果. 样例 样 ...

  4. 剑指offer:把一个支付算转化为整数

    1:首先,根据课本上的程序,是这样的: #include "stdafx.h" #include "iostream" using namespace std; ...

  5. 数据库 mysql 操作

    安装好xammp,打开阿帕奇和数据库服务: 点击右侧 shell 按钮,进入命令行: 首先,利用超级管理员权限进入数据库: mysql -uroot -p enter,再enter 把下述代码复制进命 ...

  6. 状压dfs小记

    一点前(tu)言(cao) 真的考起dfs来可谓是什么都能往dfs上套 状压不止能dp,还能与dfs结合成为搜索好(duliu)题 剪枝卡常司空见惯(打开题解一看并不是纯dfs,emmmm) 开始正文 ...

  7. [ubuntu]如何实现双屏显示

    一.首先直接运行xrandr命令,查看设备的相关信息: 运行之后会显示当前连接设备的屏幕信息,如下图 PS:我已经用HDMI线连接了外接显示器和主机 wangju@wangju-HP--G4:~$ x ...

  8. [转] 浅谈JS中的变量及作用域

    Situation One <script> var i; function sayHello() { var x=100; alert(x); x++; } sayHello();   ...

  9. CSS 易混淆属性

    1. div中 height和line-height的区别 <div style="height:120px;">是用来规定整个div的高度,文字还是默认会在顶端开始向 ...

  10. ps和top进程监控

    一.名词解释 1.什么是进程(what is process)? 答:进程是程序运行的过程,伴有动态,生命和运行状态.(组成:1.已分配内存的地址空间  2.安全属性,包括所有权凭据和特权  3.程序 ...