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

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

下面是ActiveMQ的连接factory配置:

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

下面是JmsTemplate的配置:

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

我是使用纯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

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

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

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

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

 public class TestJMS {
private String name;
private Integer age;
private String email; public TestJMS() {
} public TestJMS(String name, Integer age, String email) {
this.name = name;
this.age = age;
this.email = email;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} @Override
public String toString() {
return "TestJMS{" +
"name='" + name + '\'' +
", age=" + age +
", email='" + email + '\'' +
'}';
}
}

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

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

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

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

 import com.test.bean.TestJMS;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType; import java.util.Arrays;
import java.util.HashMap;
import java.util.Map; @Configuration
public class MQConfig { @Bean
public ActiveMQConnectionFactory getAMQFactory() {
ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory();
mqConnectionFactory.setBrokerURL("tcp://59.110.231.87:61616");
mqConnectionFactory.setTrustedPackages(Arrays.asList("com.edoctor.bean"));
return mqConnectionFactory;
} @Bean
public JmsTemplate getJmsTemplate(ActiveMQConnectionFactory cf, MessageConverter messageConverter) {
JmsTemplate jmsTemplate = new JmsTemplate(cf);
jmsTemplate.setDefaultDestinationName("EDoctor.JMSTemplate.queue2");
jmsTemplate.setMessageConverter(messageConverter);
// pubSubDomain = true 为队列模式,false为订阅发布模式
jmsTemplate.setPubSubDomain(false);
return jmsTemplate;
} @Bean
public MappingJackson2MessageConverter getJacksonMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
Map<String, Class<?>> typeIdMap = new HashMap<>();
typeIdMap.put("TestJMS", TestJMS.class);
converter.setTypeIdMappings(typeIdMap);
converter.setTypeIdPropertyName("TestJMS");
converter.setEncoding("UTF-8");
return converter;
} }

四、总结

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

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

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

    讲AMQP之前,先讲下传统的JMS的消息模型,JMS中主要有三个参与者:消息的生产者.消费者.传递消息的通道(队列或者主题),两种消息模型如下:通道是队列: 通道是队列: 通道是主题: 在JMS中,虽 ...

  2. 利用stomp.js实现websocket功能,接收ActiveMQ消息队列

    一.ActiveMQ消息发送端 package lixj; import java.util.Date; import javax.jms.Connection; import javax.jms.C ...

  3. Wpf发送接收 win32消息

    #region WPF发送和接收win32消息 public const int WM_GETTEXT = 0x0D; public const int WM_SETTEXT = 0x0C; publ ...

  4. 【Spring】使用Spring和AMQP发送接收消息(中)

    上篇讲了RabbitMQ连接工厂的作用是用来创建RabbitMQ的连接,本篇就来讲讲RabbitMQ的发送消息.通过RabbitMQ发送消息最简单的方式就是将connectionFactory Bea ...

  5. 【Spring】使用Spring和AMQP发送接收消息(下)

    上篇讲了使用RabbitMQ发送消息,本篇则来讲接收消息.在传统JMS中有两种从队列获取信息的方式,使用JmsTemplate的同步方式以及使用消息驱动pojo的异步方式.Spring AMQP也提供 ...

  6. [3] MQTT,mosquitto,Eclipse Paho---怎样使用 Eclipse Paho MQTT工具来发送订阅MQTT消息?

    在上两节,笔者主要介绍了 MQTT,mosquitto,Eclipse Paho的基本概念已经怎样安装mosquitto. 在这个章节我们就来看看怎样用 Eclipse Paho MQTT工具来发送接 ...

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

    环境搭建 1.创建maven项目(jar) 2.pom.xml添加依赖 <parent> <groupId>org.springframework.boot</group ...

  8. activemq安装与简单消息发送接收实例

    安装环境:Activemq5.11.1, jdk1.7(activemq5.11.1版本需要jdk升级到1.7),虚拟机: 192.168.147.131 [root@localhost softwa ...

  9. ActiveMQ学习总结(10)——ActiveMQ采用Spring注解方式发送和监听

    对于ActiveMQ消息的发送,原声的api操作繁琐,而且如果不进行二次封装,打开关闭会话以及各种创建操作也是够够的了.那么,Spring提供了一个很方便的去收发消息的框架,spring jms.整合 ...

随机推荐

  1. QTP入门——玩玩小飞机

    1.什么是QTP? 百度百科中对QTP是这么介绍的: ——”QTP是QuickTest Professional的简称,是一种自动化测试工具.使用QTP的目的是想用它来执行重复的自动化测试,主要是用于 ...

  2. Orchard详解--第九篇 拓展模块及引用的处理

    在分析Orchard的模块加载之前,先简要说一下因为Orchard中的模块并不是都被根(启动)项目所引用的,所以当Orchard需要加载一个模块时首先需要保证该模块所依赖的其它程序集能够被找到,那么才 ...

  3. Linux 中yum的配置

    1.进入yum的路径 cd /etc/yum.repos.d 2.将原始的repo文件移入一个新建的backup文件下做备份 mv CentOS* backup 3.在/etc/yum.repos.d ...

  4. Linux下图形数据库Neo4j单机安装

    Neo4j数据库简介 Neo4j 是一个NoSQL的图形数据库(Graph Database).Neo4j使用图(graph)相关的概念来描述数据模型,把数据保存为图中的节点以及节点之间的关系.很多应 ...

  5. ECS服务器搭建Discuz 邮箱设置,报错处理

    背景 自己想做个网站,没那么多精力,然后就看到了discuz.万网买了一个月的ecs Windows server 2008 r2 服务器,就开始着手安装环境.论坛! 建站 第一次使用discuz论坛 ...

  6. shell编程-输出(六)

    echo输出echo指令用于字符串的输出 格式:echo 字符串 直接输出字符串:string echo 'this is string-output' 用双引号,这儿也可以省略引号 转义字符:\ e ...

  7. web测试笔记

    WEB兼容性测试 一.客户端兼容性 1.浏览器的兼容性测试 a.内核角度 Tridnt内核:代表作IE.腾讯.遨游.世界之窗等 Gecko内核:代表作Firefox webkit内核:代表作Safar ...

  8. centos7 Docker私有仓库搭建及删除镜像

    如果不想用私有镜像库,你可以用docker的库 https://hub.docker.com 环境准备 环境:两个装有Docker 17.09.0-ce 的centos7虚拟机 虚拟机一:192.16 ...

  9. JSP内置九个对象Request请求对象

    jsp内置对象是什么呢? 例如Java语言使用一个对象之前需要实例化(也就是所说的new一个对象),创建对象这个过程有点麻烦,所以在jsp中提供了一些内置对象,用来实现很多jsp应用.在使用内置对象时 ...

  10. JavaScript如何计算两个日期间的时间差

    <script type="text/javascript"> /* * 获得时间差,时间格式为 年-月-日 小时:分钟:秒 或者 年/月/日 小时:分钟:秒 * 其中 ...