有时在 android kotlin 上的同一键上处理动态响应对象/数组

问题描述 投票:0回答:1

我有来自这个api的回应,并且有不同的回应

...
"value": [
    {
      "@unit": "C",
      "#text": "28"
    }
  ]

有时

"value":
    {
      "@unit": "C",
      "#text": "28"
    }

我尝试从 answer

创建这个 json 适配器和模型类
object WeatherResponse {

    open class CuacaResponse{
        @SerializedName("Success")
        val success : Boolean = false
        val row : RowBean? = null
    }

    data class RowBean(
        val data : DataBean? = null
    )

    data class DataBean (
        val forecast : ForecastBean? = null
    )

    data class ForecastBean(
        val area : List<Area>? = null
    )

    data class Area(
        @SerializedName("@id")
        val id :String?="",
        @SerializedName("@description")
        val nama :String?="",
        val parameter : List<DataMain>?=null
        )

    data class DataMain(
        @SerializedName("@description")
        val namaData :String?="",
        @SerializedName("@id")
        val id :String?="",
        @SerializedName("timerange")
        val timeRange : List<TimeRangeItem>
    )

    data class TimeRangeItem(
        // sample data : 202107241800 => 2021-07-24-18:00
        @SerializedName("@datetime")
        val datetime : String,
        @JsonAdapter(ValueClassTypeAdapter::class)
        val value : ArrayList<ValueData>? = null,
    )

    data class ValueData(
        @SerializedName("@unit")
        val unit :String?="",
        @SerializedName("#text")
        val value :String?="",
    )

    class ValueClassTypeAdapter :
        JsonDeserializer<ArrayList<ValueData?>?> {
        override fun deserialize(
            json: JsonElement,
            typeOfT: Type?,
            ctx: JsonDeserializationContext
        ): ArrayList<ValueData?> {
            return getJSONArray(json, ValueData::class.java, ctx)
        }

        private fun <T> getJSONArray(json: JsonElement, type: Type, ctx:
        JsonDeserializationContext): ArrayList<T> {
            val list = ArrayList<T>()
            if (json.isJsonArray) {
                for (e in json.asJsonArray) {
                    list.add(ctx.deserialize<Any>(e, type) as T)
                }
            } else if (json.isJsonObject) {
                list.add(ctx.deserialize<Any>(json, type) as T)
            } else {
                throw RuntimeException("Unexpected JSON type: " + json.javaClass)
            }
            return list
        }
    }
}

我的改装服务:

interface WeatherService {
    @GET("/api/cuaca/DigitalForecast-{province}.xml?format=json")
    suspend fun getWeather(
        @Path("province") provinceName: String? = "JawaTengah"
    ) : WeatherResponse.CuacaResponse?

    companion object {
        private const val URL = "https://cuaca.umkt.ac.id"
        fun client(context: Context): WeatherService {
            val httpClient = OkHttpClient.Builder()
            httpClient.apply {
                addNetworkInterceptor(
                    ChuckerInterceptor(
                        context = context,
                        alwaysReadResponseBody = true
                    )
                )

                addInterceptor { chain ->
                    val req = chain.request()
                        .newBuilder()
                        .build()
                    return@addInterceptor chain.proceed(req)
                }
                cache(null)
            }

            val gsonConverterFactory = GsonConverterFactory.create()

            return Retrofit.Builder()
                .baseUrl(URL)
                .client(httpClient.build())
                .addConverterFactory(gsonConverterFactory)
                .build()
                .create(WeatherService::class.java)
        }
    }
}

但是我从日志请求中得到的结果:

...
{
    "@datetime": "202108070000",
    "value": {
      "size": 4
    }
  },
  {
    "@datetime": "202108070600",
    "value": {
      "size": 4
    }
  },
  {
    "@datetime": "202108071200",
    "value": {
      "size": 4
    }
  }
...

value 从哪里返回 IDK 的大小,它应该从 api 返回单位数组和文本。 请任何人帮助我解决这个问题,在此先感谢!

android kotlin retrofit2 json-deserialization
1个回答
1
投票

最后,我通过将 JsonDeserializer 更改为 TypeAdapterFactory 解决了这个问题,如this answer

© www.soinside.com 2019 - 2024. All rights reserved.