升级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); } }
问题原因
- CloudEvent转换逻辑触发失败:Spring Cloud Stream 2022.0.x(适配Spring Boot 3)版本中,
CloudEventsFunctionInvocationHelper会对已配置contentType的消息尝试进行CloudEvent格式转换。当消息是纯字符串XML且项目中没有引入XML序列化/反序列化依赖(如Jackson XML模块)时,转换过程会返回null,后续代码直接调用null.getClass()导致空指针异常。 - 版本差异导致行为变化:Spring Boot 3之前的版本中,CloudEvent转换逻辑不会强制对已指定
contentType的消息执行转换,或对转换失败的场景处理更健壮,因此不会触发该异常。 - 移除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
相关产品推荐
相关产品推荐

