Spring Integration Java DSL存入Header的对象被转为String异常
问题产生原因
- 核心原因是Java DSL和Kotlin DSL中
headerFunction的overwrite(覆盖已有同名消息头)参数默认值不一致,且你使用的pollTime是Spring Integration内置保留的消息头名:在流执行到enrichHeaders组件之前,框架已经自动往消息头里写入了同名的String类型值。 - Java DSL中双参数的
headerFunction(String headerName, Function<Message<?>, V> function)方法,默认overwrite参数值为null,会继承HeaderEnricher的全局默认配置defaultOverwrite=false,即仅当目标头不存在时才会写入新值,不会覆盖已有头。你的代码里因为pollTime头已经预先存在,构造的AtomicInteger实例根本没有被写入消息头,后续拿到的一直是框架提前写入的String类型值,才会抛出类型不匹配异常。 - Kotlin DSL提供的
headerFunction扩展函数,默认将overwrite参数设为true,无论目标头是否存在都会强制覆盖为你写入的新值,因此AtomicInteger实例可以正常存入消息头,功能运行正常。 - 补充说明:
pollTime是Spring Integration的内置保留头,对应常量IntegrationMessageHeaderAccessor.POLL_TIME,默认由轮询消费者在消息生成阶段写入,值为轮询触发的时间戳,在经过类型转换、跨组件传输时很容易被转为String格式,不建议业务代码直接复用内置保留头名存储自定义值。
修复方案
在Java DSL的headerFunction调用中显式传入第三个参数overwrite=true,强制覆盖已有同名消息头即可:
.enrichHeaders(t -> t.headerFunction(pollTime, message -> new AtomicInteger(), true))
如果要彻底避免和框架内置头冲突,建议将自定义业务头重命名为非保留名称,比如customPollCount,不要和框架自动生成的pollTime、id、timestamp等保留头重名。
内容的提问来源于stack exchange,提问作者PaulNUK
相关产品推荐
相关产品推荐

