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

Spring Cloud Stream消费者反序列化异常:[B无法转换为QueueObject类

Spring Cloud Stream消费者反序列化异常:[B无法转换为QueueObject类

我之前也踩过一模一样的坑!看你的代码,Jackson的类型区分注解(@JsonTypeInfo、@JsonSubTypes)都配置得没问题,生产者也手动设置了application/json的Content-Type,但消费者还是把消息当成byte[](也就是报错里的[B)处理,核心原因是Spring Cloud Stream的消费者没有正确绑定JSON反序列化器,默认用了字节数组的处理逻辑。

下面是针对性的解决步骤,结合你的代码来调整:


1. 强制消费者使用JSON反序列化器(关键配置)

Spring Cloud Stream的Kafka binder默认会用ByteArrayDeserializer,所以必须在配置文件里给你的消费者绑定指定JSON反序列化器,同时配置信任包和类型映射。

比如在application.yml里添加:

spring:
  cloud:
    stream:
      # 配置Kafka消费者的反序列化器
      kafka:
        bindings:
          gatekeeperIn0-in-0:
            consumer:
              value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
              properties:
                # 信任你的QueueObject所在的包,防止反序列化安全限制
                spring.json.trusted.packages: in.co.nmsworks.rca.sa.inv.commons
                # 映射你的@JsonSubTypes的name到实际类路径
                spring.json.type.mapping: SimpleQObject:in.co.nmsworks.rca.sa.inv.commons.SimpleQueueObject
      # 绑定消费者的目标主题和内容类型
      bindings:
        gatekeeperIn0-in-0:
          destination: reconTrigger-out-0
          content-type: application/json

2. 确保生产者用JSON序列化消息

你已经用MessageBuilder设置了Content-Type,但最好再给生产者绑定也明确配置content-type,避免Spring用默认的Java序列化(虽然你的类实现了Serializable,但我们要的是JSON):

spring:
  cloud:
    stream:
      bindings:
        reconTrigger-out-0:
          content-type: application/json

3. 验证Jackson类型信息是否正确序列化

有时候Jackson可能因为ObjectMapper的配置问题,没有把type字段写入JSON。你可以在生产者发送前手动序列化测试,确认type字段存在:

// 在addInBuilderQueue方法里加这段测试
@Autowired
private ObjectMapper objectMapper;

private void addInBuilderQueue(InventoryDataBuilderQueueObject inventoryDataBuilderQueueObject) {
    SimpleQueueObject objs = new SimpleQueueObject(InventoryOperationType.ADD, false);
    // 测试序列化
    try {
        String json = objectMapper.writeValueAsString(objs);
        log.info("序列化后的JSON: {}", json);
    } catch (JsonProcessingException e) {
        log.error("序列化失败", e);
    }
    // 发送消息
    streamBridge.send("reconTrigger-out-0", MessageBuilder.withPayload(objs)
            .setHeader(MessageHeaders.CONTENT_TYPE, "application/json")
            .build());
}

正常输出应该包含"type":"SimpleQObject"这个属性,如果没有,说明你用的ObjectMapper没有自动识别@JsonTypeInfo注解,改用Spring容器提供的ObjectMapper bean即可(它会自动处理Jackson的类型注解)。

4. 避免泛型擦除的影响

函数式消费者Consumer<QueueObject>理论上可以被Spring正确识别类型,但如果还是有问题,可以改成接收Message<QueueObject>,明确获取payload:

@Bean
public Consumer<Message<QueueObject>> gatekeeperIn0() {
    return msg -> {
        QueueObject payload = msg.getPayload();
        log.info("Received from RECON: {}", payload);
        // 后续逻辑
    };
}

5. 排除Java序列化的干扰

你的类实现了Serializable,但现在我们用JSON序列化,这个接口其实可以暂时去掉(或者保留,但必须确保配置里没有用JavaSerializer),防止Spring误触发Java序列化逻辑。


按照上面的步骤配置后,消费者应该就能正确把JSON字节数组反序列化成SimpleQueueObject实例,不会再出现[B cannot be cast to QueueObject的错误了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 10:03:05