我们在进行发送消息的时候,正常情况下消息体为二进制的数据方式进行传输,如果希望内部帮我们进行转换,或者指定自定义的转换器,就需要用到MessageConverter

  • 自定义常用转换器:MessageConverter,一般来讲都需要实现这个接口
  • 重写下面两个方法: toMessage:java对象转换为Message fromMessage:Message对象转换为java对象
  • Json转换器:Jackson2JsonMessageConverter:可以进行Java对象的转换功能
  • DefaultJackson2JavaTypeMapper映射器:可以进行java对象的映射关系
  • 自定义二进制转换器:比如图片类型、PDF、PPT、流媒体

在pom.xml文件中加入依赖:

  1. <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
  2. <dependency>
  3. <groupId>com.fasterxml.jackson.core</groupId>
  4. <artifactId>jackson-core</artifactId>
  5. <version>2.10.0</version>
  6. </dependency>
  7.  
  8. <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
  9. <dependency>
  10. <groupId>com.fasterxml.jackson.core</groupId>
  11. <artifactId>jackson-databind</artifactId>
  12. <version>2.10.0</version>
  13. </dependency>

1.完成将byte数组转换成String字符串

上节的适配器不变,在适配器中添加一个转换器TextMessageConverter

  1. //1.适配器方式:默认是有自己的方法的名字的:handleMessage
  2. MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
  3. //自己指定一个默认的方法名
  4. adapter.setDefaultListenerMethod("consumeMessage");
  5. //也可以加一个转换器:从字节数组转换为String
  6. adapter.setMessageConverter(new TextMessageConverter());
  7. container.setMessageListener(adapter);

TextMessageConverter代码:

  1. package com.dwz.spring.converter;
  2.  
  3. import org.springframework.amqp.core.Message;
  4. import org.springframework.amqp.core.MessageProperties;
  5. import org.springframework.amqp.support.converter.MessageConversionException;
  6. import org.springframework.amqp.support.converter.MessageConverter;
  7.  
  8. public class TextMessageConverter implements MessageConverter {
  9. //将其它对象转换成Message
  10. @Override
  11. public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
  12. return new Message(object.toString().getBytes(), messageProperties);
  13. }
  14.  
  15. //将Message对象转换成String
  16. @Override
  17. public Object fromMessage(Message message) throws MessageConversionException {
  18. String contentType = message.getMessageProperties().getContentType();
  19. if(null != contentType && contentType.contains("text")) {
  20. System.err.println("contentType:--String--" + contentType);
  21. return new String(message.getBody());
  22. }
  23. return message.getBody();
  24. }
  25. }

此时我们适配器自定义的委托对象MessageDelegate的consumeMessage()接收的参数类型要与 fromMessage()返回的类型一致

MessageDelegate类如下:

  1. public class MessageDelegate {
  2. public void consumeMessage(String messageBody) {
  3. System.err.println("consumeMessage默认方法,消息内容:String--" + messageBody);
  4. }
  5. }

测试代码:

  1. @Test
  2. public void testMessage02() {
  3. //创建消息
  4. MessageProperties messageProperties = new MessageProperties();
  5. messageProperties.setContentType("text/plain");
  6. Message message = new Message("spring consumeMessage消息".getBytes(), messageProperties);
  7. rabbitTemplate.send("topic001", "spring.abc", message);
  8.  
  9. rabbitTemplate.convertAndSend("topic001", "spring.amqp", "hello object message send!");
  10.  
  11. rabbitTemplate.convertAndSend("topic002", "rabbit.amqp", "hello object message send!");
  12. }

2. 支持json格式的转换器

添加Order和Packaged这两个类

Order类:

  1. package com.dwz.spring.entity;
  2.  
  3. import java.io.Serializable;
  4. public class Order implements Serializable{
  5. private static final long serialVersionUID = 1L;
  6.  
  7. private String id;
  8.  
  9. private String name;
  10.  
  11. private String content;
  12.  
  13. public Order() {
  14. super();
  15. // TODO Auto-generated constructor stub
  16. }
  17.  
  18. public Order(String id, String name, String content) {
  19. super();
  20. this.id = id;
  21. this.name = name;
  22. this.content = content;
  23. }
  24.  
  25. public String getId() {
  26. return id;
  27. }
  28.  
  29. public void setId(String id) {
  30. this.id = id;
  31. }
  32.  
  33. public String getName() {
  34. return name;
  35. }
  36.  
  37. public void setName(String name) {
  38. this.name = name;
  39. }
  40.  
  41. public String getContent() {
  42. return content;
  43. }
  44.  
  45. public void setContent(String content) {
  46. this.content = content;
  47. }
  48.  
  49. }

Packaged类:

  1. package com.dwz.spring.entity;
  2.  
  3. import java.io.Serializable;
  4. public class Packaged implements Serializable{
  5. /**
  6. *
  7. */
  8. private static final long serialVersionUID = 1L;
  9.  
  10. private String id;
  11.  
  12. private String name;
  13.  
  14. private String description;
  15.  
  16. public Packaged() {
  17. super();
  18. // TODO Auto-generated constructor stub
  19. }
  20.  
  21. public Packaged(String id, String name, String description) {
  22. super();
  23. this.id = id;
  24. this.name = name;
  25. this.description = description;
  26. }
  27.  
  28. public String getId() {
  29. return id;
  30. }
  31.  
  32. public void setId(String id) {
  33. this.id = id;
  34. }
  35.  
  36. public String getName() {
  37. return name;
  38. }
  39.  
  40. public void setName(String name) {
  41. this.name = name;
  42. }
  43.  
  44. public String getDescription() {
  45. return description;
  46. }
  47.  
  48. public void setDescription(String description) {
  49. this.description = description;
  50. }
  51.  
  52. }

设置适配器中setMessageConverter(jackson2JsonMessageConverter)转换器参数

  1. MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
  2. adapter.setDefaultListenerMethod("consumeMessage");
  3. Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
  4. adapter.setMessageConverter(jackson2JsonMessageConverter);
  5. container.setMessageListener(adapter);

MessageDelegate类的consumeMessage()的入参修改为Map<String, Object>如下:

  1. public void consumeMessage(Map<String, Object> messageBody) {
  2. System.err.println("consumeMessage的map方法,消息内容:" + messageBody);
  3. }

测试代码:

  1. /**
  2. * 支持json格式的转换器
  3. * @throws JsonProcessingException
  4. */
  5. @Test
  6. public void testSendJsonMessage() throws JsonProcessingException {
  7. Order order = new Order();
  8. order.setId("001");
  9. order.setName("消息订单");
  10. order.setContent("描述信息");
  11.  
  12. ObjectMapper mapper = new ObjectMapper();
  13. String json = mapper.writeValueAsString(order);
  14. System.err.println("order 4 json:" + json);
  15.  
  16. MessageProperties messageProperties = new MessageProperties();
  17. //这里一定要修改contentType为application/json
  18. messageProperties.setContentType("application/json");
  19.  
  20. Message message = new Message(json.getBytes(), messageProperties);
  21. rabbitTemplate.send("topic001", "spring.order", message);
  22. }

3.支持java对象转换

更改适配器部分代码,完成Jackson2JsonMessageConverter转换器的DefaultJackson2JavaTypeMapper设置

  1. //1.2 DefaultJackson2JavaTypeMapper 和 Jackson2JsonMessageConverter 支持java对象转换
  2. MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
  3. adapter.setDefaultListenerMethod("consumeMessage");
  4. Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
  5. DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();
  6. //如果使用RabbitMQ默认的转换方式,并不会涉及到本章遇到的信任package问题,如果想自定义消息转换并且使用DefaultClassMapper作为映射,
  7. //肯定会出现信任package的问题,所以如果需要自定义转换的小伙伴,记住要设置trustedPackages。
  8. javaTypeMapper.addTrustedPackages("com.dwz.spring.entity");
  9. jackson2JsonMessageConverter.setJavaTypeMapper(javaTypeMapper);
  10. adapter.setMessageConverter(jackson2JsonMessageConverter);
  11. container.setMessageListener(adapter);

MessageDelegate类的consumeMessage()的入参修改为Order对象如下:

  1. public void consumeMessage(Order order) {
  2. System.err.println("order对象,消息内容, id:" + order.getId()
  3. +", name:" + order.getName()
  4. +", content:" + order.getContent());
  5. }

测试代码:

  1. /**
  2. * json与java对象之间的转换
  3. * @throws JsonProcessingException
  4. */
  5. @Test
  6. public void testSendJavaMessage() throws JsonProcessingException {
  7. Order order = new Order();
  8. order.setId("001");
  9. order.setName("消息订单");
  10. order.setContent("描述信息");
  11.  
  12. ObjectMapper mapper = new ObjectMapper();
  13. String json = mapper.writeValueAsString(order);
  14. System.err.println("order 4 json:" + json);
  15.  
  16. MessageProperties messageProperties = new MessageProperties();
  17. //这里一定要修改contentType为application/json
  18. messageProperties.setContentType("application/json");
  19. messageProperties.getHeaders().put("__TypeId__", "com.dwz.spring.entity.Order");
  20.  
  21. Message message = new Message(json.getBytes(), messageProperties);
  22. rabbitTemplate.send("topic001", "spring.order", message);
  23. }

4.支持java对象多映射转换

更改适配器部分代码,加入多个typeid和对象的映射

  1. //1.3 DefaultJackson2JavaTypeMapper 和 Jackson2JsonMessageConverter 支持java对象多映射转换
  2. MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
  3. adapter.setDefaultListenerMethod("consumeMessage");
  4. Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
  5. DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();
  6. Map<String, Class<?>> idClassMapping = new HashMap<String, Class<?>>();
  7. idClassMapping.put("order", Order.class);
  8. idClassMapping.put("packaged", Packaged.class);
  9. javaTypeMapper.setIdClassMapping(idClassMapping);
  10. jackson2JsonMessageConverter.setJavaTypeMapper(javaTypeMapper);
  11. adapter.setMessageConverter(jackson2JsonMessageConverter);
  12. container.setMessageListener(adapter);

MessageDelegate类的consumeMessage()添加入参为Order和Packaged对象的两个重载方法如下:

  1. public void consumeMessage(Order order) {
  2. System.err.println("order对象,消息内容, id:" + order.getId()
  3. +", name:" + order.getName()
  4. +", content:" + order.getContent());
  5. }
  6.  
  7. public void consumeMessage(Packaged pack) {
  8. System.err.println("Packaged对象,消息内容, id:" + pack.getId()
  9. +", name:" + pack.getName()
  10. +", description:" + pack.getDescription());
  11. }

测试代码:

要在Headers中添加

  1. messageProperties2.getHeaders().put("__TypeId__", "packaged");
  1. @Test
  2. public void testSendMappingMessage() throws JsonProcessingException {
  3. Order order = new Order();
  4. order.setId("001");
  5. order.setName("订单消息");
  6. order.setContent("订单描述信息");
  7.  
  8. ObjectMapper mapper = new ObjectMapper();
  9. String json1 = mapper.writeValueAsString(order);
  10. System.err.println("order 4 json:" + json1);
  11.  
  12. MessageProperties messageProperties = new MessageProperties();
  13. //这里一定要修改contentType为application/json
  14. messageProperties.setContentType("application/json");
  15. messageProperties.getHeaders().put("__TypeId__", "order");
  16.  
  17. Message message = new Message(json1.getBytes(), messageProperties);
  18. rabbitTemplate.send("topic001", "spring.order", message);
  19.  
  20. Packaged packaged = new Packaged();
  21. packaged.setId("002");
  22. packaged.setName("包裹消息");
  23. packaged.setDescription("包裹描述信息");
  24.  
  25. String json2 = mapper.writeValueAsString(packaged);
  26. System.err.println("packaged 4 json:" + json2);
  27.  
  28. MessageProperties messageProperties2 = new MessageProperties();
  29. //这里一定要修改contentType为application/json
  30. messageProperties2.setContentType("application/json");
  31. messageProperties2.getHeaders().put("__TypeId__", "packaged");
  32.  
  33. Message message2 = new Message(json2.getBytes(), messageProperties2);
  34. rabbitTemplate.send("topic001", "spring.packaged", message2);
  35. }

5.全局转换器:convert

更改适配器部分代码,加入全局转换器

  1. //1.4 全局转换器:convert
  2. MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
  3. adapter.setDefaultListenerMethod("consumeMessage");
  4.  
  5. //全局转换器
  6. ContentTypeDelegatingMessageConverter convert = new ContentTypeDelegatingMessageConverter();
  7.  
  8. TextMessageConverter textConvert = new TextMessageConverter();
  9. convert.addDelegate("text", textConvert);
  10. convert.addDelegate("html/text", textConvert);
  11. convert.addDelegate("xml/text", textConvert);
  12. convert.addDelegate("text/plain", textConvert);
  13.  
  14. Jackson2JsonMessageConverter jsonConverter = new Jackson2JsonMessageConverter();
  15. convert.addDelegate("json", jsonConverter);
  16. convert.addDelegate("application/json", jsonConverter);
  17.  
  18. ImageMessageConverter imageConverter = new ImageMessageConverter();
  19. convert.addDelegate("image/png", imageConverter);
  20. convert.addDelegate("image", imageConverter);
  21.  
  22. PDFMessageConverter pdfConverter = new PDFMessageConverter();
  23. convert.addDelegate("application/pdf", pdfConverter);
  24.  
  25. adapter.setMessageConverter(convert);
  26. container.setMessageListener(adapter);

MessageDelegate类的consumeMessage()添加方法

  1. public void consumeMessage(File file) {
  2. System.err.println("文件对象,消息内容, " + file.getName());
  3. }

添加自定义转换器ImageMessageConverter和PDFMessageConverter

  1. package com.dwz.spring.converter;
  2.  
  3. import java.io.ByteArrayInputStream;
  4. import java.io.File;
  5. import java.io.IOException;
  6. import java.nio.file.Files;
  7. import java.nio.file.Paths;
  8. import java.nio.file.StandardCopyOption;
  9. import java.util.UUID;
  10.  
  11. import org.springframework.amqp.core.Message;
  12. import org.springframework.amqp.core.MessageProperties;
  13. import org.springframework.amqp.support.converter.MessageConversionException;
  14. import org.springframework.amqp.support.converter.MessageConverter;
  15. import org.springframework.util.FileCopyUtils;
  16.  
  17. public class ImageMessageConverter implements MessageConverter {
  18.  
  19. @Override
  20. public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
  21. throw new MessageConversionException(" convert error! ");
  22. }
  23.  
  24. @Override
  25. public Object fromMessage(Message message) throws MessageConversionException {
  26. System.err.println("---------------Image MessageConverter-------------------");
  27. Object _extName = message.getMessageProperties().getHeaders().get("extName");
  28. String extName = _extName == null ? "png" : _extName.toString();
  29.  
  30. byte[] body = message.getBody();
  31. String fileName = UUID.randomUUID().toString();
  32. String path = "D:\\dwz_temp\\" + fileName + "." + extName;
  33. File f = new File(path);
  34. System.out.println(path);
  35.  
  36. try {
  37. Files.copy(new ByteArrayInputStream(body), Paths.get(path), StandardCopyOption.REPLACE_EXISTING);
  38. // FileCopyUtils.copy(body, f);
  39. } catch (IOException e) {
  40. e.printStackTrace();
  41. }
  42. return f;
  43. }
  44.  
  45. }
  1. package com.dwz.spring.converter;
  2.  
  3. import java.io.ByteArrayInputStream;
  4. import java.io.File;
  5. import java.io.IOException;
  6. import java.nio.file.Files;
  7. import java.util.UUID;
  8.  
  9. import org.springframework.amqp.core.Message;
  10. import org.springframework.amqp.core.MessageProperties;
  11. import org.springframework.amqp.support.converter.MessageConversionException;
  12. import org.springframework.amqp.support.converter.MessageConverter;
  13.  
  14. public class PDFMessageConverter implements MessageConverter {
  15.  
  16. @Override
  17. public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
  18. throw new MessageConversionException(" convert error! ");
  19. }
  20.  
  21. @Override
  22. public Object fromMessage(Message message) throws MessageConversionException {
  23. System.err.println("---------------PDF MessageConverter-------------------");
  24.  
  25. byte[] body = message.getBody();
  26. String fileName = UUID.randomUUID().toString();
  27. String path = "D:/dwz_temp/" + fileName + ".pdf";
  28. File f = new File(path);
  29. try {
  30. Files.copy(new ByteArrayInputStream(body), f.toPath());
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. }
  34. return f;
  35. }
  36. }

测试代码:

图片转换测试

  1. @Test
  2. public void testSendImgMessage1() throws IOException {
  3. byte[] body = Files.readAllBytes(Paths.get("C:/Users/Administrator/Pictures/Saved Pictures/img02/dwz.png"));
  4. MessageProperties messageProperties = new MessageProperties();
  5. messageProperties.setContentType("image/png");
  6. messageProperties.getHeaders().put("extName", "png");
  7.  
  8. Message message = new Message(body, messageProperties);
  9. rabbitTemplate.send("", "image_queue", message);
  10. }

pdf文件转换测试

  1. @Test
  2. public void testSendPDFMessage2() throws IOException {
  3. byte[] body = Files.readAllBytes(Paths.get("F:\\dwz\\my\\2019全新Java学习路线图.pdf"));
  4. MessageProperties messageProperties = new MessageProperties();
  5. messageProperties.setContentType("application/pdf");
  6.  
  7. Message message = new Message(body, messageProperties);
  8. rabbitTemplate.send("", "pdf_queue", message);
  9. }

自定义MessageConverter--消息转换器的更多相关文章

  1. SpringMVC自定义配置消息转换器踩坑总结

    问题描述 最近在开发时候碰到一个问题,springmvc页面向后台传数据的时候,通常我是这样处理的,在前台把数据打成一个json,在后台接口中使用@requestbody定义一个对象来接收,但是这次数 ...

  2. springmvc-自定义消息转换器

    最近的项目没有用到这个,先把自己自学跑通的例子先帖出来,供自己以后参考吧! 如有不对地方望指出! 一.自定义类实现AbstractHttpMessageConverter package com.dz ...

  3. ActiveMQ之spring集成消息转换器MessageConverter

    MessageConverter的作用主要有两方面,一方面它可以把我们的非标准化Message对象转换成我们的目标Message对象,这主要是用在发送消息的时候:另一方面它又可以把我们的Message ...

  4. SpringBoot 消息转换器 HttpMessageConverter

    1.简介: Spring在处理请求时,由合适的消息转换器将请求报文绑定为方法中的形参对象,在这里,同一个对象就有可能出现多种不同的消息形式,比如json和xml.同样,当响应请求时,方法的返回值也同样 ...

  5. HttpMessageConverter(消息转换器 )和@responsebody使用(转)

    @responsebody表示该方法的返回结果直接写入HTTP response body中 一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@resp ...

  6. HandlerMethodArgumentResolver(三):基于消息转换器的参数处理器【享学Spring MVC】

    每篇一句 一个事实是:对于大多数技术,了解只需要一天,简单搞起来只需要一周.入门可能只需要一个月 前言 通过 前面两篇文章 的介绍,相信你对HandlerMethodArgumentResolver了 ...

  7. Spring Boot项目中如何定制HTTP消息转换器

    在构建RESTful数据服务过程中,我们定义了controller.repositories,并用一些注解修饰它们,但是到现在为止我们还没执行过对象的转换--将java实体对象转换成HTTP的数据输出 ...

  8. 自定义WM_NOTIFY消息

    自定义WM_NOTIFY消息 习惯了用自定义用户消息进行各种状态的通知,特别是子窗口与父窗口之间的交互.但ON_MESSAGE没有控件ID的限制,如果有多个子窗口发送同一个消息给父窗口时,父窗口就不知 ...

  9. Spring MVC__自定义日期类型转换器

    WEB层采用Spring MVC框架,将查询到的数据传递给APP端或客户端,这没啥,但是坑的是实体类中有日期类型的属性,但是你必须提前格式化好之后返回给它们.说真的,以前真没这样做过,之前都是一口气查 ...

  10. SSM-SpringMVC-28:SpringMVC类型转换之自定义日期类型转换器

     ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 例子很简易,要明白的是思路,话不多说,开讲 上篇博客不是说springmvc默认的日期转换格式是yyyy/M ...

随机推荐

  1. JSON函数表1

    jsoncpp 主要包含三个class:Value.Reader.Writer.注意Json::Value 只能处理 ANSI 类型的字符串,如果 C++ 程序是用 Unicode 编码的,最好加一个 ...

  2. Java 代码运行顺序

    1.静态代码块,只执行一次,从上到下,先父类后子类 2.父类构造代码块,从上到下,然后父类构造方法,执行次数与实例化次数相关 3.子类构造代码块,从上到下,然后子类构造方法,执行次数与实例化次数相关

  3. java基础4(线程)

    1.请简单描述什么是并行,什么是并发? 并行:指两个或多个事件在同一时刻发生(同时发生). 并发:指两个或多个事件在同一个时间段内发生. 通俗易懂版: 你吃饭吃到一半,电话来了,你一直到吃完了以后才去 ...

  4. The last packet successfully received from the server was 39,900 milliseconds ago问题解决

    1,之前用Mysql或者mycat的时候都没有这个问题.后来改为haproxy+keepalived+mycat后出现这个问题 2,网上查了很多说法,我按照网上说的改了 datasource: url ...

  5. 配置Notepad++万能调试

    需求: 正常情况下 使用notepad++编辑修改一些网页或脚本文件,修改之后想要查看效果需要Ctrl+S保存,然后从文件目录中打开查看. 现在我想做的就是简化查看效果的流程,让notepad++实现 ...

  6. docker使用上的错误

    docker启动问题 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon ...

  7. gulp connect.static is not a function

    npm install --save serve-static var serveStatic = require('serve-static');

  8. lodash 中 remove

    var obj = { "objectiveDetailId": 285, "objectiveId": 29, "number": 1, ...

  9. 22_7mybaits注解开发

    这几年来注解开发越来越流行,Mybatis 也可以使用注解开发方式,这样我们就可以减少编写 Mapper 映射文件了. 1.常用注解说明 @Insert:实现新增 @Update:实现更新 @Dele ...

  10. Angular与Vue

    最近在考虑对前端js框架的选择 根据前人的总结,就总结一下 Angular与Vue 的特点与区别 速度/性能 虽然 Angular 和 Vue 都提供了很高的性能,但由于 Vue 的虚拟 DOM 实现 ...