在 moshi 中使用自定义 MapAdapter 序列化地图

Posted

技术标签:

【中文标题】在 moshi 中使用自定义 MapAdapter 序列化地图【英文标题】:Serializing a Map with custom MapAdapter in moshi 【发布时间】:2019-12-14 20:46:42 【问题描述】:

我正在尝试在moshi 中编写自定义MapAdapter 我的要求是忽略地图中的任何不良元素。我已经成功编写了反序列化方法(fromJson()),但是我遇到了toJson 的麻烦。这是我的toJson() 方法。

override fun toJson(writer: JsonWriter, value: Map<Any?, Any?>?) 
            if (value == null) 
                writer.nullValue()
             else 
                writer.beginObject()
                value.forEach 
                    writer.name(elementKeyAdapter.toJsonValue(it.key).toString())
                        .value(elementValueAdapter.toJson(it.value))
                
                writer.endObject()
            
        

这段代码的问题是它总是在最终的 Json 中将 map 中的值作为字符串写入。例如考虑这段代码

enum class VehicleType2 
    @Json(name ="type1")
    TYPE1,

    @Json(name ="type2")
    TYPE2,

    @Json(name ="type3")
    TYPE3,

    @Json(name ="type4")
    TYPE4,


        val map = mutableMapOf<VehicleType2, Int>()
        map[VehicleType2.TYPE1] = 1
        map[VehicleType2.TYPE2] = 2
        val adapter: JsonAdapter<Map<VehicleType2, Int>> =
            moshi.adapter(Types.newParameterizedType(Map::class.java, VehicleType2::class.java, Integer::class.java))
        Log.i("test", adapter.toJson(map))

这会导致跟随 Json

"type1":"1","type2":"2"

注意12strings 而不是integers。到目前为止,我尝试了很多排列都没有成功。

这里是more complete sample,它重现了这个问题。

【问题讨论】:

【参考方案1】:

经过几次尝试和错误,我发现这工作正常

                    writer.name(elementKeyAdapter.toJsonValue(it.key).toString())
                    elementValueAdapter.toJson(writer, it.value)

而不是

writer.name(elementKeyAdapter.toJsonValue(it.key).toString())
                        .value(elementValueAdapter.toJson(it.value))

我仍然不确定它背后的原因。谢谢!

【讨论】:

以上是关于在 moshi 中使用自定义 MapAdapter 序列化地图的主要内容,如果未能解决你的问题,请参考以下文章

如何在不定义类的情况下使用 moshi 创建复杂的 json?

使用 Moshi 反序列化可以是两种数据类型之一的字段

Moshi 无法将 0、1 反序列化为“布尔值?”

moshi 极简封装

moshi 极简封装

moshi 极简封装