You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何通过JMS消息转换器实现Java对象与JSON互转

核心问题解答

1. 消息体Java对象的注解要求

如果POJO严格符合JavaBean规范(提供public无参构造方法、所有需要序列化的字段提供对应public getter/setter方法),不需要强制添加任何注解即可完成基础JSON双向转换。生产环境推荐添加1个实用注解避免异常:

  • @JsonIgnoreProperties(ignoreUnknown = true):加在类上,反序列化时自动忽略JSON中存在但Java类未定义的字段,避免因消息携带冗余字段抛出反序列化错误
  • (可选)@JsonProperty("自定义字段名"):加在字段上,仅当JSON字段名和Java字段名不一致时做映射,无自定义映射需求可不加

如果使用Lombok简化代码,可按需添加@Data、@NoArgsConstructor、@AllArgsConstructor自动生成getter/setter、构造方法,这类注解属于代码简化工具注解,不属于JMS/Jackson的强制要求。

2. 消息转换器选型

直接选用Spring官方提供的MappingJackson2MessageConverter即可。该转换器基于Jackson JSON库实现,自动完成Java对象到JSON格式TextMessage的序列化、以及JSON TextMessage到Java对象的反序列化,和JmsTemplate、@JmsListener适配度最高,无额外兼容问题。

注意:不要使用已废弃的MappingJacksonMessageConverter,该实现是为Jackson 1.x版本设计的旧组件,早已停止维护。


可独立运行的Spring Boot实现方案

本方案使用嵌入式内存ActiveMQ作为消息中间件,无需额外部署外部MQ,启动即可直接运行。

第一步:引入Maven依赖

<dependencies>
    <!-- Spring JMS + 嵌入式ActiveMQ starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>
    <!-- Jackson JSON序列化依赖,引入spring-boot-starter-web可自动引入,无web依赖则手动添加 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <!-- Lombok可选,不想用可以手动写getter/setter、构造方法 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

第二步:添加应用配置

在application.yml中添加如下配置:

spring:
  activemq:
    broker-url: vm://embedded?broker.persistent=false # 启用嵌入式内存MQ,不持久化消息
    packages:
      trust-all: true # 开发环境可开启全类信任,生产环境请替换为trusted配置指定具体包路径
  jms:
    template:
      default-destination: test-json-queue # 默认发送队列名
    listener:
      acknowledge-mode: auto

生产环境建议关闭trust-all配置,通过spring.activemq.packages.trusted指定具体信任的实体类包路径,避免反序列化安全风险。

第三步:配置JMS消息转换器

编写JMS配置类,注册JSON转换器并绑定到JMS组件:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
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 jakarta.jms.ConnectionFactory;

@Configuration
@EnableJms // 开启JMS注解监听支持
public class JmsConfig {

    @Bean
    public MessageConverter jacksonJmsMessageConverter() {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        // 转换后的消息存为文本类型,JSON内容写入TextMessage
        converter.setTargetType(MessageType.TEXT);
        // 存储Java类型标识的消息属性名,反序列化时自动识别对应实体类型
        converter.setTypeIdPropertyName("_type");
        return converter;
    }

    @Bean
    public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
        JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
        jmsTemplate.setMessageConverter(messageConverter);
        return jmsTemplate;
    }
}

如果使用Spring Boot 2.x版本,将上述代码中jakarta.jms.ConnectionFactory替换为javax.jms.ConnectionFactory即可,其余代码无差异。

第四步:定义消息实体类

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserMessage implements Serializable {
    private Long userId;
    private String content;
    private LocalDateTime sendTime;
}

不使用Lombok的话,手动生成无参构造、全参构造、所有字段的getter/setter、toString方法即可,功能完全一致。

第五步:实现消息生产者

直接通过JmsTemplate发送Java对象,转换器会自动完成对象转JSON的逻辑:

import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
public class MessageProducer {
    private final JmsTemplate jmsTemplate;

    public MessageProducer(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }

    public void sendUserMessage(UserMessage message) {
        jmsTemplate.convertAndSend(message);
        System.out.printf("发送消息成功:%s%n", message);
    }
}

第六步:实现消息消费者

通过@JmsListener监听队列,方法参数直接用实体类接收,转换器会自动完成JSON转对象的逻辑:

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class MessageConsumer {

    @JmsListener(destination = "test-json-queue")
    public void receiveUserMessage(UserMessage message) {
        System.out.printf("收到消息,自动转换为UserMessage对象:%s%n", message);
        System.out.printf("字段读取结果:userId=%d,内容=%s,发送时间=%s%n",
                message.getUserId(),
                message.getContent(),
                message.getSendTime());
    }
}

第七步:编写启动类测试

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.time.LocalDateTime;

@SpringBootApplication
public class JmsJsonDemoApplication implements CommandLineRunner {

    private final MessageProducer messageProducer;

    public JmsJsonDemoApplication(MessageProducer messageProducer) {
        this.messageProducer = messageProducer;
    }

    public static void main(String[] args) {
        SpringApplication.run(JmsJsonDemoApplication.class, args);
    }

    @Override
    public void run(String... args) {
        // 应用启动后构造测试对象发送
        UserMessage testMsg = new UserMessage(
                1001L,
                "JMS JSON双向转换测试消息",
                LocalDateTime.now()
        );
        messageProducer.sendUserMessage(testMsg);
    }
}

运行验证

直接启动应用,控制台会输出如下日志,说明双向转换流程正常:

发送消息成功:UserMessage(userId=1001, content=JMS JSON双向转换测试消息, sendTime=2024-05-20T16:20:33.125)
收到消息,自动转换为UserMessage对象:UserMessage(userId=1001, content=JMS JSON双向转换测试消息, sendTime=2024-05-20T16:20:33.125)
字段读取结果:userId=1001,内容=JMS JSON双向转换测试消息,发送时间=2024-05-20T16:20:33.125

全程无需手动编写JSON序列化/反序列化逻辑,转换器会自动完成Java对象和JSON的双向映射。

内容的提问来源于stack exchange,提问作者Edie Reynolds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 04:12:30