RabbitMQ realizes the sending and receiving of JSON and Map format data

RabbitMQ is currently a very popular message middleware, which is widely used in both the Internet industry and traditional industries. RabbitMQ is favored by more and more enterprises due to its high reliability, easy expansion, high availability and rich features. In realizing project development, Json and Map format data are often used. The following will introduce RabbitMQ to realize the sending and receiving of Json and Map format data.

(1) Create SpringBoot project and integrate RabbitMQ framework

In the pom.xml configuration information file, add related dependent files:

<!-- AMQP客户端 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

Configure the RabbitMQ service in the application.yml configuration file:

spring:
  # 项目名称
  application:
    name: rabbitmq-provider
  # RabbitMQ服务配置
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    # 消息确认(ACK)
    publisher-confirm-type: correlated #确认消息已发送到交换机(Exchange)
    publisher-returns: true #确认消息已发送到队列(Queue)

(2) RabbitMQ configuration class

In the project, create a configuration class, configure message confirmation, Json converter, queue name, etc., and hand over the queue to IoC management. code show as below:

package com.pjb.config;

import com.pjb.receiver.AckReceiver;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * RabbitMQ配置类
 * @author pan_junbiao
 **/
@Configuration
public class RabbitMqConfig
{
    public static final String DIRECT_QUEUE_NAME = "direct_queue_name"; //队列名称
    public static final String DIRECT_EXCHANGE_NAME = "direct_exchange_name"; //交换器名称
    public static final String DIRECT_ROUTING_KEY = "direct_routing_key"; //路由键

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory)
    {
        final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        
        //设置Json转换器
        rabbitTemplate.setMessageConverter(jsonMessageConverter());
        
        return rabbitTemplate;
    }

    /**
     * Json转换器
     */
    @Bean
    public Jackson2JsonMessageConverter jsonMessageConverter()
    {
        return new Jackson2JsonMessageConverter();
    }

    /**
     * 队列
     */
    @Bean
    public Queue directQueue()
    {
        return new Queue(DIRECT_QUEUE_NAME, true, false, false, null);
    }

    /**
     * Direct交换器
     */
    @Bean
    public DirectExchange directExchange()
    {
        return new DirectExchange(DIRECT_EXCHANGE_NAME, true, false);
    }

    /**
     * 绑定
     */
    @Bean
    Binding bindingDirect(DirectExchange directExchange, Queue directQueue)
    {
        //将队列和交换机绑定, 并设置用于匹配键:routingKey
        return BindingBuilder.bind(directQueue).to(directExchange).with(DIRECT_ROUTING_KEY);
    }

    /********************配置客户端消息确认Ack********************/
    @Autowired
    private CachingConnectionFactory connectionFactory;

    @Autowired
    private AckReceiver ackReceiver;

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer()
    {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setConcurrentConsumers(1);
        container.setMaxConcurrentConsumers(1);

        // RabbitMQ默认是自动确认,这里改为手动确认消息
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);

        //设置一个队列
        container.setQueueNames(DIRECT_QUEUE_NAME);

        container.setMessageListener(ackReceiver);

        return container;
    }
}

 

1. Sending and receiving of data in JSON format

(1) Create entity class (entity layer)

In the com.pjb.entity package, create a UserInfo class (user information entity class).

package com.pjb.entity;

/**
 * 用户信息实体类
 * @author pan_junbiao
 **/
public class UserInfo
{
    private int userId; //用户编号
    private String userName; //用户姓名
    private String blogUrl; //博客地址
    private String blogRemark; //博客信息

    //省略getter与setter方法...
}

(2) Create a sender (sender layer)

In the com.pjb.sender package, create a sender and use the rabbitTemplate.convertAndSend() method to send the message.

package com.pjb.sender;

import com.pjb.config.RabbitMqConfig;
import com.pjb.entity.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * 发送JSON数据
 * @author pan_junbiao
 **/
@SpringBootTest
public class JsonSender
{
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Test
    public void sender() throws AmqpException
    {
        //创建用户信息
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(1);
        userInfo.setUserName("pan_junbiao的博客");
        userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");
        userInfo.setBlogRemark("您好,欢迎访问 pan_junbiao的博客");
        
        /**
         * 发送消息,参数说明:
         * String exchange:交换器名称。
         * String routingKey:路由键。
         * Object object:发送内容。
         */
        rabbitTemplate.convertAndSend(RabbitMqConfig.DIRECT_EXCHANGE_NAME, RabbitMqConfig.DIRECT_ROUTING_KEY, userInfo);
        System.out.println("消息发送成功!");
    }
}

(3) Create a receiver (receiver layer)

Method 1: Use the traditional @RabbitListener and @RabbitHandler annotations to achieve message reception.

In the com.pjb.receiver package, create a receiver, and use the traditional @RabbitListener and @RabbitHandler annotations to achieve message reception. Among the method parameters, RabbitMQ will automatically convert JSON parameters into entity object classes.

Note that the Queue name of the sender and receiver must be the same, otherwise the message cannot be received.

package com.pjb.receiver;

import com.pjb.entity.UserInfo;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import com.pjb.config.RabbitMqConfig;

import java.util.Map;

/**
 * 接收者
 * @author pan_junbiao
 **/
@Component
@RabbitListener(queues=RabbitMqConfig.DIRECT_QUEUE_NAME)
public class JsonReceiver
{
    @RabbitHandler
    public void process(UserInfo userInfo)
    {
        System.out.println("接收者收到JSON格式消息:");
        System.out.println("用户编号:" + userInfo.getUserId());
        System.out.println("用户名称:" + userInfo.getUserName());
        System.out.println("博客地址:" + userInfo.getBlogUrl());
        System.out.println("博客信息:" + userInfo.getBlogRemark());
    }
}

Method 2: Use RabbitMQ message acknowledgement mechanism (ACK)

If the RabbitMQ message acknowledgement mechanism (ACK) is used in the project, the method of obtaining data in Json format is as follows:

package com.pjb.receiver;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pjb.entity.UserInfo;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

/**
 * Ack接收者
 * @author pan_junbiao
 **/
@Component
public class AckReceiver implements ChannelAwareMessageListener
{
    @Override
    public void onMessage(Message message, Channel channel) throws Exception
    {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try
        {
            //将JSON格式数据转换为实体对象
            ObjectMapper mapper = new ObjectMapper();
            UserInfo userInfo = mapper.readValue(message.getBody(), UserInfo.class);

            System.out.println("接收者收到JSON格式消息:");
            System.out.println("用户编号:" + userInfo.getUserId());
            System.out.println("用户名称:" + userInfo.getUserName());
            System.out.println("博客地址:" + userInfo.getBlogUrl());
            System.out.println("博客信息:" + userInfo.getBlogRemark());

            //确认消息
            channel.basicAck(deliveryTag, true);
        }
        catch (Exception e)
        {
            e.printStackTrace();

            //拒绝消息
            channel.basicReject(deliveryTag, true);
        }
    }
}

Results of the:

 

2. Sending and receiving of Map format data

(1) Create a sender (sender layer)

In the com.pjb.sender package, create a sender and use the rabbitTemplate.convertAndSend() method to send the message.

package com.pjb.sender;

import com.pjb.config.RabbitMqConfig;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.Map;

/**
 * 发送Map数据
 * @author pan_junbiao
 **/
@SpringBootTest
public class MapSender
{
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Test
    public void sender() throws AmqpException
    {
        //创建用户信息Map
        Map<String, Object> userMap = new HashMap<>();
        userMap.put("userId", "1");
        userMap.put("userName", "pan_junbiao的博客");
        userMap.put("blogUrl", "https://blog.csdn.net/pan_junbiao");
        userMap.put("userRemark", "您好,欢迎访问 pan_junbiao的博客");

        /**
         * 发送消息,参数说明:
         * String exchange:交换器名称。
         * String routingKey:路由键。
         * Object object:发送内容。
         */
        rabbitTemplate.convertAndSend(RabbitMqConfig.DIRECT_EXCHANGE_NAME, RabbitMqConfig.DIRECT_ROUTING_KEY, userMap);
        System.out.println("消息发送成功!");
    }
}

(2) Create a receiver (receiver layer)

Method 1: Use the traditional @RabbitListener and @RabbitHandler annotations to achieve message reception.

In the com.pjb.receiver package, create a receiver, and use the traditional @RabbitListener and @RabbitHandler annotations to achieve message reception. In the method parameters, RabbitMQ will automatically encapsulate Map format data.

Note that the Queue name of the sender and receiver must be the same, otherwise the message cannot be received.

package com.pjb.receiver;

import com.pjb.config.RabbitMqConfig;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 接收者
 * @author pan_junbiao
 **/
@Component
@RabbitListener(queues= RabbitMqConfig.DIRECT_QUEUE_NAME)
public class MapReceiver
{
    @RabbitHandler
    public void process(Map message)
    {
        System.out.println("接收者收到Map消息:");
        System.out.println("用户编号:" + message.get("userId"));
        System.out.println("用户名称:" + message.get("userName"));
        System.out.println("博客地址:" + message.get("blogUrl"));
        System.out.println("博客信息:" + message.get("userRemark"));
    }
}

Method 2: Use RabbitMQ message acknowledgement mechanism (ACK)

If the RabbitMQ message acknowledgement mechanism (ACK) is used in the project, the method of obtaining Map format data is as follows:

package com.pjb.receiver;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * Ack接收者
 * @author pan_junbiao
 **/
@Component
public class AckReceiver implements ChannelAwareMessageListener
{
    @Override
    public void onMessage(Message message, Channel channel) throws Exception
    {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try
        {
            //将JSON格式数据转换为Map对象
            ObjectMapper mapper = new ObjectMapper();
            JavaType javaType = mapper.getTypeFactory().constructMapType(Map.class, String.class, Object.class);
            Map<String, Object> resultMap = mapper.readValue(message.getBody(),javaType);

            System.out.println("接收者收到Map格式消息:");
            System.out.println("用户编号:" + resultMap.get("userId"));
            System.out.println("用户名称:" + resultMap.get("userName"));
            System.out.println("博客地址:" + resultMap.get("blogUrl"));
            System.out.println("博客信息:" + resultMap.get("userRemark"));

            //确认消息
            channel.basicAck(deliveryTag, true);
        }
        catch (Exception e)
        {
            e.printStackTrace();

            //拒绝消息
            channel.basicReject(deliveryTag, true);
        }
    }
}

Results of the:

Guess you like

Origin blog.csdn.net/pan_junbiao/article/details/113522993