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

如何定义Data Class使Moshi序列化出指定JSON结构?

Fixing Moshi Serialization to Include Empty formValues Object

The issue you're hitting comes down to two key quirks with Moshi's default behavior:

  1. Moshi doesn't serialize classes with no properties (your FormValues is an empty class), so it gets completely omitted from the output JSON.
  2. Your formValues property is declared as a class member instead of part of the primary constructor, which can make Moshi's code generator overlook it (even with the @Json annotation, the empty class problem is the bigger blocker here).

Here are a few clean, practical solutions to get your desired JSON structure {"id":"abcdef","formValues":{}}:


Solution 1: Replace FormValues with an Empty Map (Simplest Approach)

If you don't strictly need a dedicated FormValues class, swapping it for an empty Map is the fastest way to get the empty object in your output:

@JsonClass(generateAdapter = true)
class MyDataClass(
    @Json(name = "id") val id: String,
    @Json(name = "formValues") val formValues: Map<String, Any?> = emptyMap()
)

When serialized, Moshi automatically converts the empty Map to {} in JSON, giving you exactly the structure you want without extra code.


Solution 2: Add a Custom JsonAdapter for FormValues

If you need to keep the FormValues class for your code structure, create a custom adapter to force Moshi to serialize it as an empty object:

First, define the adapter:

class FormValuesAdapter {
    @ToJson
    fun serialize(writer: JsonWriter) {
        // Explicitly write an empty JSON object
        writer.beginObject().endObject()
    }

    @FromJson
    fun deserialize(reader: JsonReader): FormValues {
        // Skip the empty object during deserialization
        reader.beginObject()
        reader.endObject()
        return FormValues()
    }
}

Then update MyDataClass to include formValues in the primary constructor (this ensures Moshi's generator reliably picks it up):

@JsonClass(generateAdapter = true)
class MyDataClass(
    @Json(name = "id") val id: String,
    @Json(name = "formValues") val formValues: FormValues = FormValues()
) {
    @JsonClass(generateAdapter = true)
    class FormValues
}

Finally, register the adapter when building your Moshi instance:

val moshi = Moshi.Builder()
    .add(FormValuesAdapter())
    .build()

val json = moshi.adapter(MyDataClass::class.java).toJson(MyDataClass("abcdef"))
// Output: {"id":"abcdef","formValues":{}}

Solution 3: Add a Dummy Property to FormValues (Quick Hack)

For a minimal change without writing a custom adapter, add a hidden dummy property to FormValues to trick Moshi into serializing it as an object:

@JsonClass(generateAdapter = true)
class MyDataClass(
    @Json(name = "id") val id: String,
    @Json(name = "formValues") val formValues: FormValues = FormValues()
) {
    @JsonClass(generateAdapter = true)
    class FormValues {
        // Dummy property to force Moshi to recognize this as a serializable class
        @Json(ignore = true) private val placeholder: Unit? = null
    }
}

This works because Moshi now sees FormValues as a class with properties (even though the only one is ignored) and will serialize it as an empty object {}.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 21:33:13