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

Kotlin使用JacksonPubSubMessageConverter发送Raw JSON双重编码如何解决

问题根因

你遇到的双重编码问题本质是JacksonPubSubMessageConverter的默认逻辑导致的:当你传入字符串类型的payload时,converter会把它当成普通Java/Kotlin对象调用objectMapper.writeValueAsBytes()做JSON序列化,字符串类型在JSON序列化时会自动包裹双引号、转义内部的双引号,最终输出的字节就是转义后的双重编码结果。
你给出的示例代码逻辑刚好复现了这个过程:已经序列化好的JSON字符串被再次做JSON序列化,导致最终的字节内容无法直接反序列化为TestClass对象。

可行解决方案

方案1:直接传入业务对象(最推荐)

JacksonPubSubMessageConverter设计初衷就是自动完成业务对象到JSON字节的序列化,你不需要自己提前把对象转成JSON字符串,直接把业务对象实例传给PubSubTemplate的发送方法即可:

// 直接构造业务对象作为payload
val payload = TestClass(value = 42)
// 传入PubSubTemplate发送,converter会自动生成正确的{"value":42}字节
pubSubTemplate.publish("你的topic名称", payload)

消费方拿到的payload字节就是标准JSON格式,可以直接反序列化为TestClass。

方案2:传入字节类型payload,绕过JSON序列化

如果你确实需要自己构造原始JSON字符串,不需要Jackson帮你做序列化,可以把JSON字符串转成ByteArray/ByteString类型再传入,JacksonPubSubMessageConverter默认不会对字节类型的payload做二次处理,会直接写入PubSub消息:

import java.nio.charset.StandardCharsets

// 自己构造的原始JSON字符串
val rawJson = "{ \"value\": 42 }"
// 转成UTF-8字节数组作为payload
val payload = rawJson.toByteArray(StandardCharsets.UTF_8)
// 直接发送字节数组即可
pubSubTemplate.publish("你的topic名称", payload)

方案3:自定义MessageConverter适配字符串payload

如果业务逻辑必须传入字符串类型的payload,又不想被二次序列化,可以自定义PubSubMessageConverter,对字符串类型做特殊处理:

class CustomPubSubMessageConverter(objectMapper: ObjectMapper) : JacksonPubSubMessageConverter(objectMapper) {
    override fun toPubSubMessage(payload: Any, headers: MutableMap<String, Any>): PubSubMessage {
        // 如果payload是字符串,直接转成字节不用JSON序列化
        if (payload is String) {
            return PubSubMessage.newBuilder()
                .setData(ByteString.copyFrom(payload, StandardCharsets.UTF_8))
                .putAllHeaders(headers)
                .build()
        }
        // 其他类型走原有Jackson序列化逻辑
        return super.toPubSubMessage(payload, headers)
    }
}

把自定义的Converter注册为Spring Bean替换默认的JacksonPubSubMessageConverter即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:06:07