第一篇是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

 

 

发表评论