第一篇是ActiveMQ的helloworld代码。
第二篇使用ActiveMQ整合Spring,非springmvc。(ActiveMQ整合SpringMVC的代码放在下一篇)
第三篇使用ActiveMQ整合SpringMVC。
JDK8+Comcat8+spring4.1.3+ActiveMQ5.15.2
项目文件:这些是ActiveMQ整合SpringMVC的所有文件,java+xml文件一共14个,下载地址在最文章下面(包括依赖的jar包)。
下面把这14个文件的代码全部贴出来。
AMQController.java
package controller; import java.text.SimpleDateFormat; import java.util.*; import javax.annotation.Resource; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.TextMessage; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import service.ConsumerService; import service.ProducerService; /** * @author 朱宏亮 * @version 创建时间:2017年12月4日 下午5:04:40 * 类说明 */ @Controller public class AMQController { //队列名:朱宏亮队列 @Resource(name="QueueDestination") private Destination QueueDestination; //订阅名:朱宏亮订阅 @Resource(name="TopicDestination") private Destination TopicDestination; //队列消息生产者 @Resource(name="producerService") private ProducerService producer; //队列消息消费者 @Resource(name="consumerService") private ConsumerService consumer; @RequestMapping({"","index"}) public String index(HttpServletRequest request){ return "index"; } @RequestMapping(value="/producer",method=RequestMethod.GET) public String producer(Model model){ System.out.println("------------打开Queue发送页面"); Date now = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time = dateFormat.format( now ); model.addAttribute("time", time); return "producer"; } @RequestMapping(value="/topicProducer",method=RequestMethod.GET) public String producer2(Model model){ System.out.println("------------打开Topic发送页面"); Date now = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time = dateFormat.format( now ); model.addAttribute("time", time); return "topicProducer"; } @RequestMapping(value="/onsend",method=RequestMethod.POST) public String producer(@RequestParam("message") String message, Model model) { System.out.println("------------正在发送 Queue"); producer.sendMessage(QueueDestination, message); return "index"; } @RequestMapping(value="/onTopicSend",method=RequestMethod.POST) public String producer2(@RequestParam("message") String message, Model model) { System.out.println("------------正在发送 Topic"); producer.sendTopicMessage(TopicDestination, message); return "index"; } @RequestMapping(value="/receive",method=RequestMethod.GET) public String queue_receive(Model model) throws JMSException { System.out.println("------------接收消息"); TextMessage tm = consumer.receive(QueueDestination); model.addAttribute("textMessage", tm.getText()); return "receive"; } }
ProducerService.java
package service; import javax.annotation.Resource; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.core.MessageCreator; import org.springframework.stereotype.Service; /** * @author 朱宏亮 * @version 创建时间:2017年12月4日 下午4:52:47 * 类说明 */ @Service public class ProducerService { @Resource(name="jmsTemplate") private JmsTemplate jmsTemplate; @Resource(name="jmsTemplate2") private JmsTemplate jmsTemplate2; /** * 向指定队列发送消息 */ public void sendMessage(Destination destination, final String msg) { System.out.println("------------向队列" + destination.toString() + "发送了消息:" + msg); jmsTemplate.send(destination, new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createTextMessage(msg); } }); System.out.println("------------向队列" + destination.toString() + "发送消息结束------------" ); } /** * 发送订阅消息 */ public void sendTopicMessage(Destination destination, final String msg) { System.out.println("------------向Topic" + destination.toString() + "发送了消息:" + msg); jmsTemplate2.send(destination, new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createTextMessage(msg); } }); System.out.println("------------向Topic" + destination.toString() + "发送消息结束------------" ); } }
ConsumerService.java
package service; import javax.annotation.Resource; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.TextMessage; import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Service; /** * @author 朱宏亮 * @version 创建时间:2017年12月4日 下午4:56:13 * 类说明 */ @Service public class ConsumerService { @Resource(name="jmsTemplate") private JmsTemplate jmsTemplate; /** * 接收消息 */ public TextMessage receive(Destination destination) { TextMessage tm = (TextMessage) jmsTemplate.receive(destination); try { System.out.println("\n从队列" + destination.toString() + "收到了消息:\t" + tm.getText()+"\n"); } catch (JMSException e) { //e.printStackTrace(); System.out.println("\n暂无消息\n"); } return tm; } }
AMQMessageListener.java
package service; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.TextMessage; import javax.jms.MessageListener; /** * @author 朱宏亮 * @version 创建时间:2017年12月5日 下午5:15:02 * 类说明 */ public class AMQMessageListener implements MessageListener { public void onMessage(Message arg) { try { String message = ((TextMessage) arg).getText(); System.out.println("MessageListener获得信息:" + message); } catch (JMSException e) { e.printStackTrace(); } } }
Consumer1.java
package service; import org.springframework.stereotype.Component; /** * @author 朱宏亮 * @version 创建时间:2017年12月6日 上午11:39:07 * 类说明 */ @Component("Consumer1") public class Consumer1 { public void receiveTopicMessage(String message) { System.out.println("订阅者1接收消息:"+message); } }
Consumer2.java
package service; import org.springframework.stereotype.Component; /** * @author 朱宏亮 * @version 创建时间:2017年12月5日 下午5:01:07 * 类说明 */ @Component("Consumer2") public class Consumer2 { public void receiveTopicMessage(String message) { System.out.println("订阅者2接收消息:"+message); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <servlet> <servlet-name>ActiveMQ</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:conf/*.xml</param-value><!-- ,classpath*:conf/ActiveMQ.xml --> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ActiveMQ</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!-- 处理编码格式 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 自动扫描该包,使SpringMVC认为包下用了 @Controller @Server @Component注解的类是控制器 --> <context:component-scan base-package="controller" /> <context:component-scan base-package="service" /> <mvc:annotation-driven /> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <!-- 定义跳转的文件的前后缀 ,视图模式配置 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/" /> <property name="suffix" value=".jsp" /> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> </bean> </beans>
ActiveMQ.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:jms="http://www.springframework.org/schema/jms" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <amq:connectionFactory id="amqConnectionFactory" brokerURL="tcp://127.0.0.1:61616" userName="admin" password="admin" /> <!-- 配置JMS连接工厂 --> <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"> <constructor-arg ref="amqConnectionFactory" /> <property name="sessionCacheSize" value="100" /> </bean> <!-- 定义消息队列(Queue) --> <bean id="QueueDestination" class="org.apache.activemq.command.ActiveMQQueue"> <!-- 设置消息队列的名字 --> <constructor-arg> <value>朱宏亮队列</value> </constructor-arg> </bean> <!-- topic目的地配置,其实不管是topic还是queue则他们的底层实现不同但是通过封装api就差不多了,而在spring中更是简单 --> <bean id="TopicDestination" class="org.apache.activemq.command.ActiveMQTopic"> <constructor-arg index="0" value="朱宏亮订阅" /> </bean> <!-- 配置JMS模板(Queue),Spring提供的JMS工具类,它发送、接收消息。 --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory" /> <property name="defaultDestination" ref="QueueDestination" /> <!-- 内部的consumer在receive方法中阻塞的时间。默认为1秒。 --> <property name="receiveTimeout" value="10000" /> <!-- true是topic,false是queue,默认是false,此处显示写出false --> <property name="pubSubDomain" value="false" /> </bean> <!-- 配置JMS模板(Queue),Spring提供的JMS工具类,它发送、接收消息。 --> <bean id="jmsTemplate2" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory" /> <property name="defaultDestination" ref="TopicDestination"></property> <!-- 进行持久化 --> <property name="deliveryMode" value="2" /> <!-- 开启订阅模式 --> <property name="pubSubDomain" value="true" /> </bean> </beans>
ActiveMQListener.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:jms="http://www.springframework.org/schema/jms" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <!-- 声明连接工厂 --> <amq:connectionFactory id="amqConnectionFactory2" brokerURL="tcp://127.0.0.1:61616" userName="admin" password="admin" /> <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --> <bean id="connectionFactory2" class="org.springframework.jms.connection.SingleConnectionFactory"> <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --> <property name="targetConnectionFactory" ref="amqConnectionFactory2"/> <property name="clientId" value="ClientId222"/> </bean> <jms:listener-container connection-factory="connectionFactory2" destination-type="durableTopic" > <jms:listener destination="朱宏亮订阅" subscription="订阅者二号" id="112" ref="Consumer2" method="receiveTopicMessage"/> </jms:listener-container> <jms:listener-container connection-factory="connectionFactory2" destination-type="durableTopic" > <jms:listener destination="朱宏亮订阅" subscription="订阅者一号" id="111" ref="Consumer1" method="receiveTopicMessage" /> </jms:listener-container> <bean id="messageListener" class="service.AMQMessageListener" /> <!-- Queue消息监听 --> <!-- and this is the message listener container --> <!-- <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory"/> <property name="destination" ref="QueueDestination"/> <property name="messageListener" ref="messageListener" /> </bean> --> </beans>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>welcome</title> </head> <body> <h1>Welcome!!!</h1> <h2><a href="producer">去发队列消息</a></h2> <h2><a href="topicProducer">发送订阅消息</a></h2> <h2><a href="receive">从队列中取一个消息</a></h2> </body> </html>
producer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JMS-Producer</title> </head> <body> <h1>JMS-Producer!!!</h1> <form action="onsend" method="post"> MessageText:<textarea name="message">${time }</textarea> <input type="submit" value="提交" /> </form> <h2><a href="index">返回主页</a></h2> </body> </html>
receive.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Receive</title> </head> <body> <h1>${textMessage }</h1> <h2><a href="index">返回主页</a></h2> </body> </html>
topicProducer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JMS-TopicProducer</title> </head> <body> <h1>JMS-TopicProducer!!!</h1> <form action="onTopicSend" method="post"> MessageText:<textarea name="message">${time }</textarea> <input type="submit" value="提交" /> </form> <h2><a href="index">返回主页</a></h2> </body> </html>
以上是所有代码,下面启动项目运行一下。
使用浏览器访问:http://localhost:8080/ActiveMQStudy/
点击第一个按钮,去发队列消息。
然后看eclipse的控制台。
------------打开Queue发送页面
点击提交,页面跳转回了首页,eclipse控制台输出:
------------正在发送 Queue ------------向队列queue://朱宏亮队列发送了消息:2017-12-08 15:29:56 ------------向队列queue://朱宏亮队列发送消息结束------------
在网页上点击第三个按钮,从队列中取一个消息。
看Eclipse控制台输出:
------------接收消息 从队列queue://朱宏亮队列收到了消息: 2017-12-08 15:29:56
回到主页,点击第二个按钮,发送订阅消息。
看Eclipse控制台输出:
------------打开Topic发送页面
点击提交按钮之后会返回主页,查看Eclipse控制台消息:
------------正在发送 Topic ------------向Topictopic://朱宏亮订阅发送了消息:2017-12-08 15:36:02 ------------向Topictopic://朱宏亮订阅发送消息结束------------ 订阅者2接收消息:2017-12-08 15:36:02 订阅者1接收消息:2017-12-08 15:36:02
这就是一个基本的ActiveMQ整合SpringMVC的功能介绍,我使用ActiveMQ.xml配置了Queue消息队列的发送和接收,在ActiveMQListener.xml文件中配置了两个Topic消息的监听。所以在上面最后一步点击发送Topic消息之后,在Eclipse的控制台自动打印了被发送的消息。
接下来,我们将Queue消息也改为自动监听打印的。
打开ActiveMQListen.xml文件,将最下面被我注释掉的代码取消注释,然后重启项目。
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory"/> <property name="destination" ref="QueueDestination"/> <property name="messageListener" ref="messageListener" /> </bean>
重启项目之后,打开主页,点击第一个按钮去发队列消息,在新打开的页面中点击提交,这时查看Eclipse的控制台输出信息:
------------打开Queue发送页面 ------------正在发送 Queue ------------向队列queue://朱宏亮队列发送了消息:2017-12-08 15:45:15 MessageListener获得信息:2017-12-08 15:45:15 ------------向队列queue://朱宏亮队列发送消息结束------------
程序运行的非常完美,就是这么简单。
所有源代码下载地址:https://gitee.com/zhuhongliang/ActiveMQStudy