0

There is a Json file which is put to val fileInString: String. This string looks simplistically like this.

{ "groups": 2, "group1": [ { "word": "test11", "description": "desc11" }, { "word": "test12", "description": "desc12" }, ... { "word": "test1n", "description": "desc1n" } ], "group2": [ { "word": "test21", "description": "desc21" }, ... { "word": "test2n", "description": "desc2n" } ] }

I try to convert it by using Moshi in a way below

private lateinit var dictionary: Dictionary
...
        val moshi = Moshi.Builder()
            .addLast(KotlinJsonAdapterFactory())
            .build()
        val adapter: JsonAdapter<Dictionary> = moshi.adapter(Dictionary::class.java)
        this.dictionary = adapter.fromJson(fileInString)!!

where Dictionary is a data class

data class Dictionary(
    val groups: Int,
    val group1: List<WordPair>,
    val group2: List<WordPair>
)

data class WordPair(
    val word: String,
    val description: String
)

It works fine but I'd like more universal solution because the number of groups is going to be increased and I don't want to recompile application every time it happen.

It seems using Map of Map<String, List> look good at the stage. But if I try to implement something like this

data class Dictionary(
    val groups: Int,
    val dict: Map<String, List<WordPair>>
//    val group1: List<WordPair>,
//    val group2: List<WordPair>
)

then I get an error:

"java.lang.RuntimeException: com.squareup.moshi.JsonDataException: Required value 'dict' missing at $"

which is quite fair so there is no any key/value "dict" at json string.

I would expect to get an advise regarding of data class implementation or any possible Moshi settings.. Probably custom deserialization is also a solutiom, I don't know. Thanks!

3
  • This is your json file or are you get it from somewhere? You can simplify it to achieve that without creating "groupN" objects in my opinion. Then "Dictionary" will be simpler to convert Commented Jan 19, 2024 at 12:30
  • damienG, okay, thanks! I'll consider your opinion as an option. The json file is actually under discussion so it's still possible to change it. But just curious.. What might the solution look like for this current file..:) Commented Jan 19, 2024 at 19:24
  • I think, you need to create custom adapter to handle it. Below i past for you my solution for this problem BUT i using converter-gson NOT moshi but i hope i might be helpful for you Commented Jan 22, 2024 at 9:33

1 Answer 1

0

Reminder, this is not exact resolution of problem

@JsonAdapter(DirectoryCustomAdapter::class)
data class Dictionary(
var groups: Int? = null,
var dict: MutableMap<String, List<WordPair>> = mutableMapOf()
)
data class WordPair(
val word: String,
val description: String)

class DirectoryCustomAdapter: JsonDeserializer<Dictionary> {
override fun deserialize(
    json: JsonElement?,
    typeOfT: Type?,
    context: JsonDeserializationContext?
): Dictionary {
    val dictionary: Dictionary = Dictionary()
    json?.let {
        val jsonObject = it.asJsonObject

        jsonObject.entrySet().forEach { entry ->
            if (entry.key == "groups") {
                dictionary.groups = entry.value.asInt
            } else if ((entry.value is Iterable<*>)) {
                dictionary.dict[entry.key] = (entry.value as Iterable<*>).toList() as List<WordPair>
            }
        }
    }
    return dictionary
}}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.