全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-22 8 分钟 ✍️ juanwangdev

JSON 序列化

JSON是RabbitMQ消息体的常用格式,需在发送前序列化对象、接收后反序列化还原。

定义

JSON序列化将Java对象转换为JSON字节数组作为消息体,接收方将字节数组还原为Java对象。相比原生Java序列化,JSON具备跨语言兼容与可读性强的优势。

Maven 依赖

XML
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
</dependency>

序列化与反序列化工具类

Java
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonSerializer {
    private static final ObjectMapper MAPPER = new ObjectMapper();
    
    // 对象转JSON字节数组
    public static byte[] serialize(Object obj) throws Exception {
        return MAPPER.writeValueAsBytes(obj);
    }
    
    // JSON字节数组转对象
    public static <T> T deserialize(byte[] data, Class<T> clazz) throws Exception {
        return MAPPER.readValue(data, clazz);
    }
}

发送端示例

Java
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class JsonProducer {
    private static final String QUEUE_NAME = "json_queue";
    
    public static void main(String[] args) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            
            // 构建消息对象
            OrderMessage order = new OrderMessage("ORD-001", "iPhone 15", 1, 7999.0);
            
            // 序列化为JSON字节数组
            byte[] body = JsonSerializer.serialize(order);
            
            // 设置content_type标识
            channel.basicPublish("", QUEUE_NAME, 
                createJsonProperties(), body);
            System.out.println("已发送订单消息: " + order);
        }
    }
    
    private static com.rabbitmq.client.AMQP.BasicProperties createJsonProperties() {
        return new com.rabbitmq.client.AMQP.BasicProperties.Builder()
                .contentType("application/json")
                .contentEncoding("UTF-8")
                .build();
    }
}

// 消息实体类
class OrderMessage {
    private String orderId;
    private String productName;
    private int quantity;
    private double price;
    
    public OrderMessage() {}
    
    public OrderMessage(String orderId, String productName, int quantity, double price) {
        this.orderId = orderId;
        this.productName = productName;
        this.quantity = quantity;
        this.price = price;
    }
    
    // getter/setter省略
    public String getOrderId() { return orderId; }
    public void setOrderId(String orderId) { this.orderId = orderId; }
    public String getProductName() { return productName; }
    public void setProductName(String productName) { this.productName = productName; }
    public int getQuantity() { return quantity; }
    public void setQuantity(int quantity) { this.quantity = quantity; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
    
    @Override
    public String toString() {
        return "OrderMessage{" + "orderId='" + orderId + "', productName='" + productName + "'}";
    }
}

接收端示例

Java
import com.rabbitmq.client.*;
import java.io.IOException;

public class JsonConsumer {
    private static final String QUEUE_NAME = "json_queue";
    
    public static void main(String[] args) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            
            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                byte[] body = delivery.getBody();
                
                try {
                    // 反序列化为订单对象
                    OrderMessage order = JsonSerializer.deserialize(body, OrderMessage.class);
                    System.out.println("收到订单消息: " + order);
                    
                    // 验证content_type
                    String contentType = delivery.getProperties().getContentType();
                    if (!"application/json".equals(contentType)) {
                        System.err.println("警告: 消息类型不匹配, 期望 application/json, 实际: " + contentType);
                    }
                    
                    channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
                } catch (Exception e) {
                    System.err.println("JSON反序列化失败: " + e.getMessage());
                    channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, false);
                }
            };
            
            channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});
        }
    }
}

注意事项

必须在消息属性中设置 contentType = "application/json",以便消费者识别消息格式并做相应处理。

Jackson默认要求实体类有无参构造函数,否则需配置Creator或使用@JsonCreator注解。

JSON序列化不包含类型信息,反序列化时需明确指定目标类型,或使用@JsonTypeInfo注解保留类型。

对于包含敏感信息的字段,使用@JsonIgnore@JsonProperty(access = Access.WRITE_ONLY)避免序列化。

Jackson 高级配置

Java
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public class AdvancedJsonSerializer {
    private static final ObjectMapper MAPPER;
    
    static {
        MAPPER = new ObjectMapper();
        // 忽略未知字段
        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 格式化日期
        MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        // 支持Java 8时间
        MAPPER.registerModule(new JavaTimeModule());
    }
    
    public static byte[] serialize(Object obj) throws Exception {
        return MAPPER.writeValueAsBytes(obj);
    }
    
    public static <T> T deserialize(byte[] data, Class<T> clazz) throws Exception {
        return MAPPER.readValue(data, clazz);
    }
}

要点总结

  • JSON序列化将对象转换为字节数组,作为RabbitMQ消息体传输
  • 发送端序列化,接收端反序列化,需保持序列化配置一致
  • 必须设置contentType = "application/json"标识消息格式
  • Jackson是主流选择,需配置无参构造函数或Creator
  • 反序列化时验证contentType可避免格式不匹配错误
  • 高级场景需配置日期格式、Java 8时间支持、忽略未知字段等

📝 发现内容有误?点击此处直接编辑

← 上一篇 集群架构模式
下一篇 → Protobuf 序列化
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库