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

如何将Jackson对象属性序列化为转义JSON字符串?

如何在Jackson中实现对象到转义JSON字符串的泛型序列化(无需新建ObjectMapper)

问题分析

你需要将对象序列化为转义后的JSON字符串作为属性值,但当前实现新建了ObjectMapper,这会导致配置不一致(比如丢失已注册的模块、序列化特性),同时也不够高效。

解决方案:复用现有SerializerProvider配置

可以通过SerializerProvider获取目标类型的序列化器,将对象序列化到临时缓冲区,再将结果作为转义字符串写入最终的JsonGenerator,完全复用原有配置。

基础泛型序列化器实现

class ObjectAsEscapedStringSerializer<T> : JsonSerializer<T>() {
    override fun serialize(value: T, gen: JsonGenerator, serializers: SerializerProvider) {
        // 获取当前对象类型对应的序列化器
        val valueSerializer = serializers.findValueSerializer(value.javaClass)
        // 创建临时Writer捕获序列化结果
        val stringWriter = StringWriter()
        // 基于现有配置创建临时JsonGenerator
        val tempGenerator = serializers.codec.factory.createGenerator(stringWriter)
        
        // 执行序列化到临时缓冲区
        valueSerializer.serialize(value, tempGenerator, serializers)
        tempGenerator.close()
        
        // 将捕获的JSON字符串作为转义后的字符串写入目标生成器
        gen.writeString(stringWriter.toString())
    }
}

支持泛型参数化类型的增强实现

如果目标类型是带泛型参数的(比如List<AType>),可以通过createContextual方法获取正确的类型信息:

class ObjectAsEscapedStringSerializer<T> : JsonSerializer<T>() {
    private var valueSerializer: JsonSerializer<T>? = null

    override fun createContextual(prov: SerializerProvider, property: BeanProperty?): JsonSerializer<*> {
        // 获取当前属性的具体类型
        val targetType = property?.type ?: throw IllegalArgumentException("无法获取属性类型信息")
        // 获取对应类型的序列化器
        val serializer = prov.findValueSerializer(targetType) as JsonSerializer<T>
        val newSerializer = ObjectAsEscapedStringSerializer<T>()
        newSerializer.valueSerializer = serializer
        return newSerializer
    }

    override fun serialize(value: T, gen: JsonGenerator, serializers: SerializerProvider) {
        val serializer = valueSerializer ?: throw IllegalStateException("序列化器未初始化")
        val stringWriter = StringWriter()
        val tempGenerator = serializers.codec.factory.createGenerator(stringWriter)
        
        serializer.serialize(value, tempGenerator, serializers)
        tempGenerator.close()
        
        gen.writeString(stringWriter.toString())
    }
}

方案优势

  1. 配置一致性:完全复用当前SerializerProvider的配置(比如已注册的JavaTimeModule、日期序列化特性等),避免新建ObjectMapper导致的行为差异。
  2. 性能更优:不需要重复创建ObjectMapper实例,减少资源开销。
  3. 泛型支持:增强版实现可以处理带泛型参数的复杂类型。

使用方式

和你原来的用法一致,直接在属性上添加注解:

class MyClass(
    @field:JsonSerialize(using = ObjectAsEscapedStringSerializer::class)
    val value : AType
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:15:54