Spring使用MappingJackson2MessageConverter发送接收ActiveMQ消息

Easter79
• 阅读 739

一、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为主题

二、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

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

Spring使用MappingJackson2MessageConverter发送接收ActiveMQ消息

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

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

Spring使用MappingJackson2MessageConverter发送接收ActiveMQ消息

这个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的解析也顺应主流技术。因为踩了较多的坑,所以特地留此篇博客,如果不对的地方,还希望多多指出。有疑问欢迎留言,谢谢!
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
6个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
6
获赞
1.2k