Issue
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!
Solution
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
}}
Answered By - damienG
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.