本文介绍了使用注释在带有嵌套事件的 Moshi 中序列化 Null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当从 Moshi 调用 toJSON 方法时,我试图添加自定义注释以将模型中的特定值序列化为 null.我有一些基于此 响应 但是当我有一个嵌套对象时,它对我来说不够用.

I am attempting to add a custom annotation to serialize specific values in my model to null when calling the toJSON method from Moshi. I have something working based on this response but it's falling short for me when I have a nested object.

@JsonClass(generateAdapter = true)
data class EventWrapper(
    @SerializeNulls val event: Event?,
    @SerializeNulls val queries: Queries? = null) {

    @JsonClass(generateAdapter = true)
    data class Queries(val stub: String?)

    @JsonClass(generateAdapter = true)
    data class Event(
       val action: String?,
       val itemAction: String)
}

如果我将 null 传递给 eventqueries,它们将被序列化为:

If I pass null to event or queries they are serialized as:

{
    'event': null,
    'query': null
}

问题是当事件不为空时,其中有字段我不想序列化,如果它们为空,例如动作.我的首选结果是:

The issue is when event isn't null there are fields inside of it I would like to not serialize if they are null such as action. My preferred result would be this:

{
    'event': {
        'itemAction': "test"
    },
    'query': null
}

但我得到的是:

{
    'event': {
        'action': null,
        'itemAction': "test"
    },
    'query': null
}

以下是基于链接响应的自定义适配器代码:

Here is the code for my custom adapter based on the linked response:

@Retention(RetentionPolicy.RUNTIME)
 @JsonQualifier
 annotation class SerializeNulls {
     companion object {
         var JSON_ADAPTER_FACTORY: JsonAdapter.Factory = object : JsonAdapter.Factory {

             @RequiresApi(api = Build.VERSION_CODES.P)
             override fun create(type: Type, annotations: Set<Annotation?>, moshi: Moshi): JsonAdapter<*>? {
                 val nextAnnotations = Types.nextAnnotations(annotations, SerializeNulls::class.java)

                 return if (nextAnnotations == null) {
                     null
                 } else {
                     moshi.nextAdapter<Any>(this, type, nextAnnotations).serializeNulls()
                 }
        }
    }
}

推荐答案

我遇到了同样的问题,我找到的唯一解决方案是制作自定义适配器而不是使用 SerializeNulls 注释.这样,它只会在对象为空时序列化空值,否则使用生成的适配器正常序列化它.

I've had the same issue and the only solution I found was to make a custom adapter instead of using the SerializeNulls annotation. This way, it will only serialize nulls if the object is null, and serialize it normally with the generated adapter otherwise.

class EventJsonAdapter {
    private val adapter = Moshi.Builder().build().adapter(Event::class.java)

    @ToJson
    fun toJson(writer: JsonWriter, event: Event?) {
        if (event == null) {
            with(writer) {
                serializeNulls = true
                nullValue()
                serializeNulls = false
            }
        } else {
            adapter.toJson(writer, event)
        }
    }
}

为了使生成的适配器工作,不要忘记使用以下注释对 Event 类进行注释:

For the generated adapter to work don't forget to annotate the Event class with:

@JsonClass(generateAdapter = true)

然后可以像这样将自定义适配器添加到 moshi 构建器:

The custom adapter can then be added to the moshi builder like this:

Moshi.Builder().add(EventJsonAdapter()).build()

在我的情况下,我只需要一个特定模型.如果您需要多个,可能不是一个好的解决方案,在这种情况下,注释更实用,但我将其留在这里,因为它可能对其他人有所帮助.

In my case I only needed this for one model in specific. Probably not a good solution if you need it for several, in which case the annotation is more practical, but I'll leave it here since it might help someone else.

这篇关于使用注释在带有嵌套事件的 Moshi 中序列化 Null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 05:34