使用 GSON 来自 Json 的 Kotlin 数据类

Posted

技术标签:

【中文标题】使用 GSON 来自 Json 的 Kotlin 数据类【英文标题】:Kotlin Data Class from Json using GSON 【发布时间】:2017-10-22 09:54:15 【问题描述】:

我有这样的 Java POJO 类:

class Topic 
    @SerializedName("id")
    long id;
    @SerializedName("name")
    String name;

我有一个像这样的 Kotlin 数据类

 data class Topic(val id: Long, val name: String)

如何将json key 提供给kotlin data class 的任何变量,例如java 变量中的@SerializedName 注释?

【问题讨论】:

你是如何在 Java 中做到这一点的?举个例子。 什么是 json 选择器? @voddan 我所说的那些 json 选择器的意思是我可以用来选择特定 json 对象/数组的字符串:在我的例子中是 "topic", "id","image" 。我希望我对你说清楚了。谢谢:) @nhaarman 我已经编辑了这个问题,我希望这就是你的意思 【参考方案1】:

数据类:

data class Topic(
  @SerializedName("id") val id: Long, 
  @SerializedName("name") val name: String, 
  @SerializedName("image") val image: String,
  @SerializedName("description") val description: String
)

转 JSON:

val gson = Gson()
val json = gson.toJson(topic)

来自 JSON:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)

【讨论】:

只有在变量名不匹配时才使用注释。否则,是的,不需要 在我看来,注释允许我们拥有在序列化时可以排除或包含变量的类。与改装一起使用时非常有用。这不会向服务器发送垃圾。还有,当服务器端的变量名发生变化时,直接在类变量中改比在注解中更痛苦。 @Vik 要注意的一件事是您的变量名可能会被混淆(就像在 android 应用程序中一样),但注释将保持不变 @AntonGolovin 我无法通过 Json 方法传入我的数据类。我需要在 java 文件中声明我的数据类吗? 如果你这样做,我相信你会丢失 JSON 格式,这可能会导致 IllegalStateException【参考方案2】:

基于Anton Golovin的回答

详情

Gson 版本:2.8.5 Android Studio 3.1.4 Kotlin 版本:1.2.60

解决方案

创建任意类数据并继承JSONConvertable接口

interface JSONConvertable 
     fun toJSON(): String = Gson().toJson(this)


inline fun <reified T: JSONConvertable> String.toObject(): T = Gson().fromJson(this, T::class.java)

用法

数据类

data class User(
    @SerializedName("id") val id: Int,
    @SerializedName("email") val email: String,
    @SerializedName("authentication_token") val authenticationToken: String) : JSONConvertable

来自 JSON

val json = "..."
val object = json.toObject<User>()

转 JSON

val json = object.toJSON()

【讨论】:

你为什么用SerializedName注解而不是字段命名策略,Vasily? @Peter 因为@SerializedName 将允许我使用可能与 json 键不匹配的变量的自定义名称。是的,如果你不需要@SerializedName,你可能不会使用它。【参考方案3】:

你可以在 Kotlin 类中使用类似

class InventoryMoveRequest 
    @SerializedName("userEntryStartDate")
    @Expose
    var userEntryStartDate: String? = null
    @SerializedName("userEntryEndDate")
    @Expose
    var userEntryEndDate: String? = null
    @SerializedName("location")
    @Expose
    var location: Location? = null
    @SerializedName("containers")
    @Expose
    var containers: Containers? = null

对于嵌套类,如果有嵌套对象,您也可以使用相同的方法。只需为类提供序列化名称。

@Entity(tableName = "location")
class Location 

    @SerializedName("rows")
    var rows: List<Row>? = null
    @SerializedName("totalRows")
    var totalRows: Long? = null


所以如果从服务器获得响应,每个键都将映射到 JOSN。

另外,将 List 转换为 JSON:

val gson = Gson()
val json = gson.toJson(topic)

android 从 JSON 转换为 Object:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)

【讨论】:

以上是关于使用 GSON 来自 Json 的 Kotlin 数据类的主要内容,如果未能解决你的问题,请参考以下文章

如何在 kotlin 中通过 GSON lib 解析 JSON 时管理 android 应用程序的空值

如何在 Android 的 Kotlin 中使用 GSON 将 JSON 对象转换为 JSON 数组

Kotlin 使用 Gson 将 json 字符串转换为对象列表

构建 Kotlin 类以使用 Gson 将 json 响应转换为类

Kotlin如何使用GSON解析动态JSON字段?

如何使用带有 Kotlin 的 Gson 库访问 JSON 有效负载中的嵌套值