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

使用Test Container PubSub模拟器时遭遇JSON反序列化问题

问题分析与解决

核心原因

测试环境中发布消息时未指定正确的content-type头,导致JacksonPubSubMessageConverter未将JSON字符串解析为Consumer对象,而是直接传递原始字符串。Spring尝试将该字符串转换为Consumer实例时,因没有接收String参数的构造函数而抛出异常。

生产环境通过控制台发送消息时,默认会设置content-type: application/json,因此转换器能正常解析JSON负载。

解决步骤

1. 发布消息时添加JSON类型的Content-Type头

修改发布消息的代码,在headers中指定消息内容类型为JSON:

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.cloud.gcp.pubsub.support.PubSubHeaders;

// ...

HttpHeaders headers = new HttpHeaders();
headers.set(PubSubHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
publisherTemplate.publish("My_Topic", "{\"name\": \"test\"}", headers);

2. 修正InboundChannelAdapter的OutputChannel配置

你的配置代码中存在笔误:adapter.setOutputChannel(messageChannel);引用的messageChannel未定义,应替换为你创建的inputMessageChannel:

@Bean
public PubSubInboundChannelAdapter inboundChannelAdapter(MessageChannel inputMessageChannel, PubSubTemplate pubSubTemplate) {
    PubSubInboundChannelAdapter adapter = new PubSubInboundChannelAdapter(pubSubTemplate, "my_sub");
    adapter.setOutputChannel(inputMessageChannel); // 修正此处
    adapter.setAckMode(AckMode.MANUAL);
    adapter.setPayloadType(Consumer.class);
    return adapter;
}

3. 确保测试中预创建Topic和Subscription

PubSub模拟器启动后无默认的Topic和Subscription,需在测试初始化时创建:

import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gcp.pubsub.core.PubSubTemplate;

// ...

@Autowired
private PubSubTemplate pubSubTemplate;

@BeforeEach
void setupPubSubResources() {
    // 创建Topic(不存在则创建)
    if (!pubSubTemplate.existsTopic("My_Topic")) {
        pubSubTemplate.createTopic("My_Topic");
    }
    // 创建Subscription(不存在则创建)
    if (!pubSubTemplate.existsSubscription("my_sub")) {
        pubSubTemplate.createSubscription("my_sub", "My_Topic");
    }
}

4. 确认Jackson配置生效

确保测试类能扫描到PubSubConsumerConfiguration配置类,比如测试类添加@SpringBootTest注解(若配置类在Spring Boot扫描路径下),或者显式导入配置:

@SpringBootTest
@Import(PubSubConsumerConfiguration.class)
public class PubSubIntegrationTest {
    // 测试代码
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:01:21