使用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
相关产品推荐
相关产品推荐

