Home > Software engineering >  json converter error = moshi Expected a string but was BEGIN_OBJECT at path
json converter error = moshi Expected a string but was BEGIN_OBJECT at path

Time:10-28

How to config Moshi so that below field2 from JSON
will be converted to String "{"subfield21":"asdf","subfield22":"1234"}"
in code MyData.field2

JSON:

{
   "field1":"someValue1",
   "field2":{
      "subfield21":"asdf",
      "subfield22":"1234",
   }
}

Kotlin class:

data class MyData(
  val field1: String, val field2: String
)

Whan I try std Moshi config I get an exception:

moshi Expected a string but was BEGIN_OBJECT at path

Note: I'm using standalone Moshi, without retrofit.

CodePudding user response:

You can't fit object inside string.

Try

data class MyData(
  val field1: String, val field2: SubMyData
)
data class SubMyData(
  val subfield21: String, val subfield22: String
)

CodePudding user response:

The key is JsonReader.nextSource(). Here's an adapter factory to do the job.

@Retention(RUNTIME)
@JsonQualifier
annotation class JsonString {
  object Factory {
    @JsonString @FromJson fun fromJson(reader: JsonReader): String {
      return reader.nextSource().use(BufferedSource::readUtf8)
    }

    @ToJson fun toJson(writer: JsonWriter, @JsonString value: String) {
      writer.valueSink().use { sink ->
        sink.writeUtf8(value)
      }
    }
  }
}

And here's how you can use it, using the JsonQualifier annotation we made above.

@JsonClass(generateAdapter = true)
data class MyData(
  val field1: String, @JsonString val field2: String
)

fun main() {
  val moshi = Moshi.Builder()
    .add(JsonString.Factory)
    .build()
  val adapter = moshi.adapter(MyData::class.java)
  val decoded = adapter.fromJson(json)!!
  decoded.field2 == """{"subfield21":"asdf","subfield22":"1234",}"""
}
  • Related