gson 数据类动态更改可序列化名称

ve7v8dk2  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(210)

我刚开始实习,我被要求用Retrofit等进行一些基本的实现。我有一个Json响应,它有一个根据请求参数更改的键值,我不知道如何获得该键值。
"就像这样"

{
  "status": {
    /*Some other unimportant JSON here */
  },
  "data": {
    "KEY_THAT_CHANGES": {
      "id": 74,
      /* more JSON here */
    }
  }
}

我想有多种解决方案可以获得该密钥:通过索引(因为它总是“data”中的第一个键)或通过将可序列化名称作为参数传递(因为我已经有了键)或使用自定义的反序列化类。

**请求函数:**Json中的key与symbol参数相同

@Headers(API_KEY)
    @GET("v1/cryptocurrency/info")
    fun getCoin(@Query("symbol")symbol: String):Call<CoinInfo>

我有以下数据类来保存数据:

data class CoinInfo(
    val `data`: Data,
    val status: Status
)

data class Status(
    val credit_count: Int,
    val elapsed: Int,
    val error_code: Int,
    val error_message: Any,
    val notice: Any,
    val timestamp: String
)

data class Data(
    val Coin: Coin //Here is the problem, the key is dynamically changing
)

data class Coin(
    val category: String,
    val date_added: String,
    val description: String,
    val id: Int,
    val is_hidden: Int,
    val logo: String,
    val name: String,
    val notice: String,
    val platform: Any,
    val slug: String,
    val subreddit: String,
    val symbol: String,
    @SerializedName("tag-groups")
    val tag_groups: List<String>,
    @SerializedName("tag-names")
    val tag_names: List<String>,
    val tags: List<String>,
    val twitter_username: String,
    val urls: Urls
)

请求呼叫

val api = Retrofit.Builder()
             .baseUrl(BASE_URL)
             .addConverterFactory(GsonConverterFactory.create())
             .build()
             .create(getRequest::class.java)

GlobalScope.launch(Dispatchers.IO) {
     val response = api.getCoin(coin.symbol).awaitResponse() // coin.symbol is also the key of the JSON

            if(response.isSuccessful){
                val data = response.body()!!

                withContext(Dispatchers.Main){
                    // TO DO
                }
            }
        }

我找不到任何有用的解决方案,我只是开始学习Kotlin约36小时前。

oaxa6hgo

oaxa6hgo1#

假设您的api提供CoinBill,那么您可以如下建模:

data class Data(
    val Coin: Coin?,
    val bill: Bill?
)

如果我没记错的话,gson会将missing keys设置为null,这样你就可以在以后检查实际交付的内容了。当你有一个已知数量的对象,它们彼此之间有很大的不同时,这是一个可以接受的解决方案。
如果你的硬币对象在结构上没有区别,或者你有无限多的名字,那么你最有可能应该改变你的api,做一些类似于下面的事情:

data class Coin(
    val myCoinIdentifier: String, /* 1-ct-coin, 2-ct-coin, 5-ct-coin...  */
    ...
)

关于风格:

  • 不建议调用类Data,因为这是你能给予的最通用的描述。另外,data可能是一个保留的类,请参见data class。相反,使用实际有用的名称
  • 变量名应以小写字母开头,以区别于它们所代表的类,例如,使用val coin: Coin,而不是val Coin: Coin
  • 我们不在变量名中使用下划线,使用camel大小写,例如tagGroups,而不是tag_groups
  • 您应该有一个很好的理由通过网络发送any,难道您不能进一步说明吗?
  • 您不应该需要'data'周围的单刻度

相关问题