SpringBoot整合RabbitMQ(二):定制MessageConverter

上一篇文章里面,我们已经可以发送简单的text数据到消息队列里面了。

但是在我们平常的需求里面,发送简单的文本数据是不多见的,更多的是需要JSON类型的数据,所以简单的数据发送已经不满足我们的需求了,那让我们来尝试一下发送和接收JSON数据吧!

我们先看一下RabbitMQ默认是哪个消息转换器吧

可以在RabbitTemplate的构造器打上断点查看SpringBoot默认注入的messageConverter是什么 

@Bean
		@ConditionalOnSingleCandidate(ConnectionFactory.class)
		@ConditionalOnMissingBean(RabbitTemplate.class)
		public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) 


从上图能看出,默认注入的是SimpleMessageConverter,可以追踪一下看看~

public RabbitTemplate(ConnectionFactory connectionFactory) {
		this();
		setConnectionFactory(connectionFactory);
	}

public RabbitTemplate() {
		initDefaultStrategies();
	}

protected void initDefaultStrategies() {
		setMessageConverter(new SimpleMessageConverter());
	}

这样就很明了了。先来看一下MessageConverter的层级关系图:


相信看到这个的大兄弟们都知道了,类名就很明确这个类是干啥用的了。

这边我就以Json数据为例子,我们需要用Jackson2JsonMessageConverter这个消息转换器。

@Configuration
public class MyRabbitMQConf {
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }
}

已经注入了我们所希望看到的Jackson2JsonMessageConverter转换器了,那我们开始用起来吧。

@Test
    public void contextLoads() {
        Map<Object, Object> map = new HashMap<>();
        map.put("Springboot", "Hello,baby!");
        map.put("RabbitMQ", "Yes,come on!");
        rabbitTemplate.convertAndSend("dai.topic", "dai.test.idea", map);
        Map<Object, Object> o = (Map<Object, Object>) rabbitTemplate.receiveAndConvert("dai.topic-queue");
        System.out.println(o.get("Springboot"));
        System.out.println(o.get("RabbitMQ"));
    }
为了丰富一下博文,就来看一下它如何转换数据吧?
@Override
	public void convertAndSend(String exchange, String routingKey, final Object object) throws AmqpException {
		convertAndSend(exchange, routingKey, object, (CorrelationData) null);
	}

public void convertAndSend(String exchange, String routingKey, final Object object, CorrelationData correlationData) throws AmqpException {
		send(exchange, routingKey, convertMessageIfNecessary(object), correlationData);
	}

protected Message convertMessageIfNecessary(final Object object) {
		if (object instanceof Message) {
			return (Message) object;
		}
		return getRequiredMessageConverter().toMessage(object, new MessageProperties());
	}
上面是三步,为了方便,我就放在一起了,从上往下 (读者打个断点就能清清楚楚看到了)
@Override
	public final Message toMessage(Object object, MessageProperties messageProperties)
			throws MessageConversionException {
		if (messageProperties == null) {
			messageProperties = new MessageProperties();
		}
		Message message = createMessage(object, messageProperties);
		messageProperties = message.getMessageProperties();
		if (this.createMessageIds && messageProperties.getMessageId() == null) {
			messageProperties.setMessageId(UUID.randomUUID().toString());
		}
		return message;
	}
主要是在createMessage这个方法:
@Override
	protected Message createMessage(Object objectToConvert, MessageProperties messageProperties)
			throws MessageConversionException {
		byte[] bytes;
		try {
			String jsonString = this.jsonObjectMapper
					.writeValueAsString(objectToConvert);
			bytes = jsonString.getBytes(getDefaultCharset());
		}
		catch (IOException e) {
			throw new MessageConversionException(
					"Failed to convert Message content", e);
		}
		messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
		messageProperties.setContentEncoding(getDefaultCharset());
		messageProperties.setContentLength(bytes.length);

		if (getClassMapper() == null) {
			getJavaTypeMapper().fromJavaType(this.jsonObjectMapper.constructType(objectToConvert.getClass()),
					messageProperties);

		}
		else {
			getClassMapper().fromClass(objectToConvert.getClass(),
					messageProperties);

		}

		return new Message(bytes, messageProperties);
	}
这里先贴出全部的代码,下面慢慢消化:
String jsonString = this.jsonObjectMapper.writeValueAsString(objectToConvert);
这里是转换成为json数据:

然后再将json字符串变成byte数组。
messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);

public static final String CONTENT_TYPE_JSON = "application/json";

然后就是设置一些属性,包括拿到原消息的JavaType

最后得到的messageProperties:


最后就返回一个Message,然后让它跑完吧(如何发送消息就不看了,技术还是渣渣,先研究一下,后续文章可能会写发送消息的这个过程)。再来看看是否发送成功了


注意红色部分,是不是在刚才我们创建message的时候就已经组装好了?已经能够正常发送消息了,那么接收消息呢?



很好,完美!!!那就顺便来看一下收到的消息是怎么转换的

@Override
	public Object fromMessage(Message message)
			throws MessageConversionException {
		Object content = null;   //要返回的内容就在这里
		MessageProperties properties = message.getMessageProperties();//这个MessageProperties跟发送的那时候那个配置是一样的
		if (properties != null) {
			String contentType = properties.getContentType();
			if (contentType != null && contentType.contains("json")) {//是json的content-type
				String encoding = properties.getContentEncoding();//UTF-8
				if (encoding == null) {
					encoding = getDefaultCharset();
				}
				try {

					if (getClassMapper() == null) {
						JavaType targetJavaType = getJavaTypeMapper()//这里的JavaType是java.util.HashMap
								.toJavaType(message.getMessageProperties());
						content = convertBytesToObject(message.getBody(),//拿到结果,结果截图放在下面
								encoding, targetJavaType);
					}
					else {
						Class<?> targetClass = getClassMapper().toClass(
								message.getMessageProperties());
						content = convertBytesToObject(message.getBody(),
								encoding, targetClass);
					}
				}
				catch (IOException e) {
					throw new MessageConversionException(
							"Failed to convert Message content", e);
				}
			}
			else {
				if (log.isWarnEnabled()) {
					log.warn("Could not convert incoming message with content-type ["
							+ contentType + "], 'json' keyword missing.");
				}
			}
		}
		if (content == null) {
			content = message.getBody();
		}
		return content;
	}

这就是从消息队列中获取到的消息!

然后再来简单的搞一下发送一个实体类吧。消息转换器用SerializerMessageConverter。记得实体类要实现Serializable

@Test
    public void contextLoads2() {
        Student stu = new Student();
        stu.setName("靓仔浩");
        stu.setAge(22);
        rabbitTemplate.convertAndSend("dai.topic", "dai.test.idea", stu);
        Student o = (Student) rabbitTemplate.receiveAndConvert("dai.topic-queue");
        System.out.println(stu.toString());

    }




好了,都能正常收发信息了。这个消息转换是挺简单的,看各自的需求选择需要收发的消息

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot整合RabbitMQ是相对容易的,因为SpringBoot提供了简化的配置和自动化的集成。首先,你需要对RabbitMQ有一定的了解,了解它的基本概念和工作原理。然后,你需要在你的SpringBoot项目中添加相应的依赖。在pom.xml文件中,你需要添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 这些依赖将帮助你引入RabbitMQ和Web相关的功能。接下来,你需要配置RabbitMQ的连接信息。在application.properties或application.yml文件中,你可以设置RabbitMQ的主机名、端口号、用户名、密码等信息。例如: ``` spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest ``` 一旦你完成了依赖和配置的设置,你就可以开始使用RabbitMQ了。你可以创建消息生产者和消息消费者,使用RabbitTemplate发送和接收消息。你还可以使用@RabbitListener注解来监听消息队列,并处理接收到的消息。 总结起来,整合SpringBootRabbitMQ的步骤包括:了解RabbitMQ的基本概念和工作原理、添加依赖、配置连接信息、创建消息生产者和消费者、发送和接收消息。希望这个简要的教程对你有所帮助。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* [SpringBoot如何整合RabbitMQ](https://blog.csdn.net/ShuSheng0007/article/details/125921491)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [SpringBoot整合RabbitMQ](https://blog.csdn.net/K_kzj_K/article/details/106642250)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值