Retrofit2 и Gson, десериализация данных внутри определенного элемента json - PullRequest
0 голосов
/ 27 февраля 2019

Внутри моего приложения я вызываю некоторые удаленные API, которые дают мне ответ, завернутый в бесполезный «корневой» элемент json.Я вставляю вам пример ответа json

{
 "response": {
     "status": {
         //here status fields, common to all responses
      },
      "configuration": {
          //here configurations fields
      }
  }
}

Я использую расширение студии Android для генерации классов данных kotlin (JsonToKotlinClass) и получаю четыре класса kotlin:

-MyResponseClass, Response, Status, Configuration

, где MyResponseClass похож на

data class MyResponseClass(
    val response: Response
)

, есть способ избежать создания класса "Response", анализируя только его относительное содержимое json, и получить MyResponseClass, похожий на

data class MyResponseClass(
    val status:Status,
    val configuration: Configuration
)

?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Из заголовка вашего вопроса я предполагаю, что вы хотите автоматически разобрать ответ json на более простой MyResponseClass

Этого можно добиться с помощью адаптера типа для gson.В вашем случае класс адаптера будет выглядеть следующим образом.

class MyResponseClassAdapter : JsonDeserializer<MyResponseClass> {
   override fun deserialize(jsonElement: JsonElement, p1: Type?, p2: JsonDeserializationContext?): MyResponseClass {
  val content = jsonElement.asJsonObject["response"]
  return  Gson().fromJson(content , MyResponseClass::class.java)
}
}

Затем добавьте этот адаптер в экземпляр gson и используйте этот экземпляр gson с вашим экземпляром для модификации.

 val gson = GsonBuilder()
            .registerTypeAdapter(MyResponseClass::class.java, MyResponseClassAdapter ())
            .create()

 Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
            .baseUrl("{base_url}")
            .client(okHttp)
            .build()
0 голосов
/ 27 февраля 2019

Да, когда вы получаете объект, вместо того, чтобы сразу конвертировать его, конвертируйте его следующим образом

val jsonObject = JSONObject("data")
val innerObject = jsonObject.getJSONObject("status")

и затем конвертируйте внутренний объект с помощью gson.

Это, конечно, может бытьминимизируется так:

val object = Gson().fromJson(JSONObject("response").getJSONObject("status"), MyResponseClass::class.java)
...