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

升级Spring Boot3时StreamBridge发送XML消息报空指针异常求助

问题分析:Spring Boot 3.0.3下StreamBridge发送XML消息触发空指针异常

问题场景

将项目升级至Spring Boot 3.0.3后,在@SpringBootTest测试中使用StreamBridge发送contentType为application/xml的消息时,触发如下空指针异常:

java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "result" is null
at org.springframework.cloud.function.cloudevent.CloudEventsFunctionInvocationHelper.doPostProcessResult(CloudEventsFunctionInvocationHelper.java:138)
at org.springframework.cloud.function.cloudevent.CloudEventsFunctionInvocationHelper.postProcessResult(CloudEventsFunctionInvocationHelper.java:114)
at org.springframework.cloud.function.cloudevent.CloudEventsFunctionInvocationHelper.postProcessResult(CloudEventsFunctionInvocationHelper.java:48)
at org.springframework.cloud.stream.function.StreamBridge.send(StreamBridge.java:181)
at org.springframework.cloud.stream.function.StreamBridge.send(StreamBridge.java:144)
at org.springframework.cloud.stream.function.StreamBridge.send(StreamBridge.java:140)
at com.example.demo.DemoApplicationTests.shouldSendMessage(DemoApplicationTests.java:33)

通过start.spring.io创建全新项目仍可复现,核心配置如下:

build.gradle(简化版)

plugins {
  id 'java'
  id 'org.springframework.boot' version '3.0.3'
  id 'io.spring.dependency-management' version '1.1.0'
}

ext {
  set('springCloudVersion', "2022.0.1")
}

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-amqp'
  implementation 'org.springframework.cloud:spring-cloud-stream'
  implementation 'org.springframework.cloud:spring-cloud-stream-binder-rabbit'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
  testImplementation 'org.springframework.amqp:spring-rabbit-test'
  testImplementation 'org.springframework.cloud:spring-cloud-stream-test-binder'
}

application.yml

spring:
  cloud:
    stream:
      bindings:
        demo-out-0:
          destination: some.topic
          contentType: application.xml   # 移除该行后测试通过
      rabbit:
        bindings:
          demo-out-0:
            producer:
              routingKeyExpression: '''some.routing.key'''

测试代码

@SpringBootTest
@Import(TestChannelBinderConfiguration.class)
class DemoApplicationTests {

    @Autowired
    private StreamBridge streamBridge;

    @Autowired
    private OutputDestination outputDestination;

    @Test
    void shouldSendMessage() {
        var minimalXml = """
                <?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
                <Config></Config>
                """;

        streamBridge.send("demo-out-0", MessageBuilder.withPayload(minimalXml).build());

        var actual = outputDestination.receive(1000, "some.topic");

        Assertions.assertThat(new String(actual.getPayload()))
                .isEqualTo(minimalXml);
    }
}

问题原因

  1. CloudEvent转换逻辑触发失败:Spring Cloud Stream 2022.0.x(适配Spring Boot 3)版本中,CloudEventsFunctionInvocationHelper会对已配置contentType的消息尝试进行CloudEvent格式转换。当消息是纯字符串XML且项目中没有引入XML序列化/反序列化依赖(如Jackson XML模块)时,转换过程会返回null,后续代码直接调用null.getClass()导致空指针异常。
  2. 版本差异导致行为变化:Spring Boot 3之前的版本中,CloudEvent转换逻辑不会强制对已指定contentType的消息执行转换,或对转换失败的场景处理更健壮,因此不会触发该异常。
  3. 移除contentType配置后的行为:移除绑定配置中的contentType后,消息默认使用text/plain类型,不会触发XML相关的转换逻辑,因此测试可以正常通过。

临时解决方案

  • 手动指定消息contentType:发送消息时覆盖绑定配置的类型,比如设置为text/plain:
    MessageBuilder.withPayload(minimalXml)
                  .setHeader(MessageHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE)
                  .build()
    
  • 添加XML序列化依赖:引入Jackson XML模块,让CloudEvent转换可以正常完成,比如在Gradle中添加:
    implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml'
    
  • 禁用原生编码转换:配置生产者使用原生编码,跳过CloudEvent转换逻辑:
    spring:
      cloud:
        stream:
          function:
            bindings:
              demo-out-0:
                producer:
                  use-native-encoding: true
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 08:10:41