Spring Boot 1.5.9集成RabbitMQ遇byte[]转CustomClass转换异常求助
这个问题我在处理Spring Cloud Stream Edgware版本(搭配Spring Boot 1.5.x)时也碰到过,本质是消息序列化/反序列化的配置不匹配,导致接收端无法把RabbitMQ传递的原始byte[]数据转成你的自定义CustomClass对象,下面是具体的解决步骤:
1. 先确保发送端正确标记消息的内容类型
Spring Cloud Stream需要明确知道消息的序列化格式,不然发送端会默认把对象转成byte[]发送,但不会告诉接收端怎么解码。
方式一:发送消息时显式设置Header
在发送CustomClass对象的时候,给消息加上CONTENT_TYPE头,指定用JSON格式(最常用的场景):
import org.springframework.messaging.support.MessageBuilder; import org.springframework.http.MediaType; // 在TransferController的发送逻辑里 CustomClass customObj = new CustomClass(); // 构建消息并指定内容类型 var message = MessageBuilder.withPayload(customObj) .setHeader(org.springframework.messaging.MessageHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .build(); channel.send(message);
方式二:通过配置文件全局设置生产者的内容类型
在application.yml(或application.properties)里给你的输出通道指定默认的content-type,这样所有发送到这个通道的消息都会自动用JSON序列化:
spring: cloud: stream: bindings: moneyTransferredChannel: # 对应你@Output注解的通道名称 producer: content-type: application/json
2. 给接收端配置对应的消息转换器
Edgware版本的Spring Cloud Stream不会自动注册JSON转换器到接收端,所以需要我们显式添加:
创建一个配置类,注册MappingJackson2MessageConverter(Jackson的消息转换器,用来处理JSON和Java对象的互转):
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.converter.MappingJackson2MessageConverter; import org.springframework.messaging.converter.MessageConverter; @Configuration public class StreamMessageConverterConfig { @Bean public MessageConverter jsonMessageConverter() { return new MappingJackson2MessageConverter(); } }
同时别忘了在接收端的配置里同步指定content-type,确保和发送端一致:
spring: cloud: stream: bindings: moneyTransferredChannel: # 接收端的通道名称,必须和发送端完全一致 consumer: content-type: application/json
3. 检查CustomClass的序列化兼容性
Jackson反序列化CustomClass的时候有几个必要条件,缺一不可:
- 必须有无参构造函数(Jackson需要通过无参构造创建对象再赋值)
- 字段要有对应的getter/setter方法,或者用
@JsonProperty直接标注字段(如果不想写getter/setter) - 如果用了自定义序列化规则(比如
@JsonSerialize/@JsonDeserialize),发送端和接收端的配置必须完全一致
4. 校验通道名称的一致性
最后再确认一下发送端和接收端的通道名称完全匹配:
- 发送端:
@Output("moneyTransferredChannel") - 接收端:
@Input("moneyTransferredChannel")以及@StreamListener("moneyTransferredChannel")
如果通道名称不匹配,消息根本不会路由到你的接收方法,也可能间接导致类似的转换异常(因为接收端拿到的是其他通道的byte[]数据)。
内容的提问来源于stack exchange,提问作者Rene Enriquez

