Spring使用MappingJackson2MessageConverter发送接收ActiveMQ消息

一、Spring使用JmsTemplate简化对JMS的访问

在JAVA对JMS队列访问中,使用默认的JMS支持将存在大量的检查型异常。通过Spring的支持,可以将所有的JMS的检查型异常转换为运行时非检查异常。以及在Spring中,通过配置JMSConnectionFactory的DefaultDestinationName指定发送和接收目的地。

下面是ActiveMQ的连接factory配置:

1     @Bean
2     public ActiveMQConnectionFactory getAMQFactory() {
3         ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory();
4         mqConnectionFactory.setBrokerURL("tcp://59.110.231.87:61616");
5         mqConnectionFactory.setTrustedPackages(Arrays.asList("com.edoctor.bean"));
6         return mqConnectionFactory;
7     }

下面是JmsTemplate的配置:

1     @Bean
2     public JmsTemplate getJmsTemplate(ActiveMQConnectionFactory cf, MessageConverter messageConverter) {
3         JmsTemplate jmsTemplate = new JmsTemplate(cf);
4         jmsTemplate.setDefaultDestinationName("com.demo.testActiveMQ");
5         jmsTemplate.setMessageConverter(messageConverter);
6         // pubSubDomain = true 为队列模式,false为订阅发布模式
7         jmsTemplate.setPubSubDomain(false);
8         return jmsTemplate;
9     }

我是使用纯JAVA注解配置的Bean,基于xml的也类似,可以自行搜索。

上述字段含义如下:

setDefaultDestinationName:设置ActiveMQ的队列名称,当然如果下面的pubSubDomain为true,则为主题名称

setMessageConverter:设置ActiveMQ的消息转换器,默认不写的话是使用的Spring的SimpleMessageConverter

setPubSubDomain:值true代表该Template为队列,false为主题

2.Spring的消息转换器的种类

Spring自带的消息转换器可以大大简化消息的读取以及写入,所有的消息转换器都位于org.springframework.jms.support.converter包中。

消息转换器 功能
MappingJacksonMessageConverter
使用Jackson JSON库实现消息与JSON格式之间的相互转换

MappingJackson2MessageConverter
使用Jackson 2 JSON库实现消息与JSON格式之间相互转换

MarshallingMessageConverter
使用JAXB库实现消息与XML格式之间的相互转换

SimpleMessageConverter
实现String与TextMessage之间的相互转换,字节数组与Bytes
Message之间的相互转换,Map与MapMessage之间的相互转换
以及Serializable对象与ObjectMessage之间的相互转换

默认情况下,JmsTemplate在convertAndSend()方法中会使用SimpleMessage Converter。但是通过将消息转换器声明为bean并将其注入到JmsTemplate的messageConverter属性中,我们可以重写这种行为。例如,如果你想使用JSON消息的话,那么可以声明一个MappingJackson2MessageConverter bean。

三、配置MappingJackson2MessageConverter的Bean

上文的JmsTemplate已经成功注入了ActiveMQConnectionFactory,下面就将注入我们的MessageConverter。

由于使用默认的SimpleMessageConverter如果是Object对象的话,必须将对象序列化,如果对象包含包装类例如Integer将无法实现序列化,因此,我打算使用基于json的MappingJackson2MessageConverter序列化对象发送以及接受,该配置会实现自动序列化。但是在网上查阅相关文档,发现几乎没有中文介绍配置MappingJackson2MessageConverter的,因此,希望写下这个配置帮助大家。

MappingJackson2MessageConverter在JavaDoc中的详细配置:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jms/support/converter/MappingJackson2MessageConverter.html

对于文档和介绍,上述链接有详细说明,里面主要提到一点:

意思是,如果需要在接受Object对象格式的消息的时候,需要配置这项属性,以及这项属性需要参考typeIdMappings。

我们再看一下这个Map的说明:

这个Map以String为key,Class为值,而这里的Key就是对应的typeId,Value就是你需要序列化的类。所以只需要构建这样一个Map就可以允许从MQ中接受类对象型的消息了。下面是我的POJO(注意该在MQ中发送接收的对象务必有无参构造函数)

 1 public class TestJMS {
 2     private String name;
 3     private Integer age;
 4     private String email;
 5
 6     public TestJMS() {
 7     }
 8
 9     public TestJMS(String name, Integer age, String email) {
10         this.name = name;
11         this.age = age;
12         this.email = email;
13     }
14
15     public String getName() {
16         return name;
17     }
18
19     public void setName(String name) {
20         this.name = name;
21     }
22
23     public Integer getAge() {
24         return age;
25     }
26
27     public void setAge(Integer age) {
28         this.age = age;
29     }
30
31     public String getEmail() {
32         return email;
33     }
34
35     public void setEmail(String email) {
36         this.email = email;
37     }
38
39     @Override
40     public String toString() {
41         return "TestJMS{" +
42                 "name=‘" + name + ‘\‘‘ +
43                 ", age=" + age +
44                 ", email=‘" + email + ‘\‘‘ +
45                 ‘}‘;
46     }
47 }

以及这是注入到JmsTemplate的MappingJackson2MessageConverter的Bean定义

 1     @Bean
 2     public MappingJackson2MessageConverter getJacksonMessageConverter() {
 3         MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
 4         converter.setTargetType(MessageType.TEXT);
 5         // 定义了typeId到Class的Map
 6         Map<String, Class<?>> typeIdMap = new HashMap<>();
 7         typeIdMap.put("TestJMS", TestJMS.class);
 8         converter.setTypeIdMappings(typeIdMap);
 9         // 设置发送到队列中的typeId的名称
10         converter.setTypeIdPropertyName("TestJMS");
11         converter.setEncoding("UTF-8");
12         return converter;
13     }

通过这样的注入,实现了Class Object格式无须序列化的对象发送与接受

完整的ActiveMQ基于JAVA注解的配置代码如下:

 1 import com.test.bean.TestJMS;
 2 import org.apache.activemq.ActiveMQConnectionFactory;
 3 import org.springframework.context.annotation.Bean;
 4 import org.springframework.context.annotation.Configuration;
 5 import org.springframework.jms.core.JmsTemplate;
 6 import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
 7 import org.springframework.jms.support.converter.MessageConverter;
 8 import org.springframework.jms.support.converter.MessageType;
 9
10 import java.util.Arrays;
11 import java.util.HashMap;
12 import java.util.Map;
13
14 @Configuration
15 public class MQConfig {
16
17     @Bean
18     public ActiveMQConnectionFactory getAMQFactory() {
19         ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory();
20         mqConnectionFactory.setBrokerURL("tcp://59.110.231.87:61616");
21         mqConnectionFactory.setTrustedPackages(Arrays.asList("com.edoctor.bean"));
22         return mqConnectionFactory;
23     }
24
25     @Bean
26     public JmsTemplate getJmsTemplate(ActiveMQConnectionFactory cf, MessageConverter messageConverter) {
27         JmsTemplate jmsTemplate = new JmsTemplate(cf);
28         jmsTemplate.setDefaultDestinationName("EDoctor.JMSTemplate.queue2");
29         jmsTemplate.setMessageConverter(messageConverter);
30         // pubSubDomain = true 为队列模式,false为订阅发布模式
31         jmsTemplate.setPubSubDomain(false);
32         return jmsTemplate;
33     }
34
35     @Bean
36     public MappingJackson2MessageConverter getJacksonMessageConverter() {
37         MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
38         converter.setTargetType(MessageType.TEXT);
39         Map<String, Class<?>> typeIdMap = new HashMap<>();
40         typeIdMap.put("TestJMS", TestJMS.class);
41         converter.setTypeIdMappings(typeIdMap);
42         converter.setTypeIdPropertyName("TestJMS");
43         converter.setEncoding("UTF-8");
44         return converter;
45     }
46
47 }

四、总结

MappingJackson2MessageConverter可以很有效的实现MQ的发送和接受序列化,不需要将POJO手动序列化,实现Serializable接口。基于JSON的解析也顺应主流技术。因为踩了较多的坑,所以特地留此篇博客,如果不对的地方,还希望多多指出。有疑问欢迎留言,谢谢!

原文地址:https://www.cnblogs.com/gdyblog/p/MappingJackson2MessageConverter.html

时间: 2024-10-12 13:33:22

Spring使用MappingJackson2MessageConverter发送接收ActiveMQ消息的相关文章

【Spring】使用Spring和AMQP发送接收消息(上)

讲AMQP之前,先讲下传统的JMS的消息模型,JMS中主要有三个参与者:消息的生产者.消费者.传递消息的通道(队列或者主题),两种消息模型如下:通道是队列: 通道是队列: 通道是主题: 在JMS中,虽然通道有助于解耦消息的生产者和消费者,但这两者依然会与通道相耦合.生产者会将消息发布到一个特定的队列或主题上,消费者从特定的队列或主题上接收这些消息,通道具有双重责任,就是传递数据和确定这些消息该发送到什么地方,队列的话会使用点对点算法发送,主题的话就使用发布-订阅方式.而使用AMQP的话,生产者并

Wpf发送接收 win32消息

#region WPF发送和接收win32消息 public const int WM_GETTEXT = 0x0D; public const int WM_SETTEXT = 0x0C; public const int WM_SIZEING = 0x0214; public const int WM_COPYDATA = 0x004A; public const int WM_LBUTTONDBLCLK = 0x0203; public struct Win32Message { publ

[3] MQTT,mosquitto,Eclipse Paho---如何使用 Eclipse Paho MQTT工具来发送订阅MQTT消息?

在上两节,笔者主要介绍了 MQTT,mosquitto,Eclipse Paho的基本概念已经如何安装mosquitto. 在这个章节我们就来看看如何用 Eclipse Paho MQTT工具来发送接收MQTT消息.Eclipse Paho MQTT工具是一个基于Java的Eclipse桌面客户端程序,其底层的和MQTT服务器进行的交互的java类库就是Eclipse Paho java库.假设我们在本机(127.0.0.1)已经启动了一个mosquitto MQTT服务器,其端口为1883.如

解决Springboot整合ActiveMQ发送和接收topic消息的问题

环境搭建 1.创建maven项目(jar) 2.pom.xml添加依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> </parent> <dependencies> &l

ActiveMQ如何接收离线消息

[消息持久化] ActiveMQ持久订阅设置 通过为发布者设置 PERSISTENT传送模式,为订阅者时使用持久订阅,这样可以保证 Pub/Sub 程序接收所有发布的消息. 消息订阅分为非持久订阅(non-durable subscription)和持久订阅(durable subscription),非持久订阅只有当客户端处于激活状态,也就是和 ActiveMQ 保持连接状态才能收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会丢失,永远不会收到.持久订阅时,客户端

SpringBoot整合RabbitMQ之发送接收消息实战

实战前言 前几篇文章中,我们介绍了SpringBoot整合RabbitMQ的配置以及实战了Spring的事件驱动模型,这两篇文章对于我们后续实战RabbitMQ其他知识要点将起到奠基的作用的.特别是Spring的事件驱动模型,当我们全篇实战完毕RabbitMQ并大概了解一下RabbitMQ相关组件的源码时,会发现其中的ApplicationEvent.ApplicationListener.ApplicationEventPublisher跟RabbitMQ的Message.Listener.R

2015年12月10日 spring初级知识讲解(三)Spring消息之activeMQ消息队列

基础 JMS消息 一.下载ActiveMQ并安装 地址:http://activemq.apache.org/ 最新版本:5.13.0 下载完后解压缩到本地硬盘中,解压目录中activemq-core-5.13.0.jar,这就是ActiveMQ提供给我们的API. 在bin目录中,找到用于启动ActiveMQ的脚本,运行脚本后ActiveMQ就准备好了,可以使用它进行消息代理. 访问http://127.0.0.1:8161/admin/能看到如下则表示安装成功了. 二.在Spring中搭建消

Java Socket发送与接收HTTP消息简单实现

在上次Java Socket现实简单的HTTP服务我 们实现了简单的HTTP服务,它可以用来模拟HTTP服务,用它可以截获HTTP请求的原始码流,让我们很清楚的了解到我们向服务发的HTTP消息的结 构,对HTTP请求消息有个清晰的认识.这一节我想写了一个客户的程序,就是用来模拟浏览器,用来向服务器发送HTTP请求,最得要的是可以用它来显示服 务器发回来的HTTP响应消息的一般结构. [java] view plaincopy import java.io.IOException; import 

ActiveMQ 消息服务(二)

本文介绍ActiveMQ的几种通信方法: 本文转自:http://shmilyaw-hotmail-com.iteye.com/blog/1897635  这篇文章总结的太好了,不得不转啊! 简介 在前面一篇文章里讨论过几种应用系统集成的方式,发现实际上面向消息队列的集成方案算是一个总体比较合理的选择.这里,我们先针对具体的一个消息队列 Activemq的基本通信方式进行探讨.activemq是JMS消息通信规范的一个实现.总的来说,消息规范里面定义最常见的几种消息通信模式主要有 发布-订阅.点