【问题标题】:Java/Kotlin JSON parsing improvementJava/Kotlin JSON 解析改进
【发布时间】:2017-08-13 07:51:42
【问题描述】:

我使用了一个 API,它为我提供了这种类型的 JSON:

{
  "data": {
    "name": "Start",
    "pid": "1",
    "position": {
      "data": {
        "x": "31",
        "y": "330"
      },
      "metadata": "empty"
    }
  },
  "metadata": "empty"
}

我已经创建了具有与上述 JSON 结构相同的对象的类。我在 Android 中使用 retrofit 库,内部使用 GSON 来解析 JSON。

我的模型类会是这样的:

MResponse.class

public class MResponse {

    @SerializedName("data")
    public User user;

    String metadata;
}

User.class

public class User {

    public String name;

    public String pid;

    @SerializedName("position")
    public PositionData positionData;
}

PositionData.class

public class PositionData {

    @SerializedName("data")
    public Position position;

    public String metadata;
}

Position.class

public class Position {

    public String x;

    public String y;
}

现在这对我来说很好。但是正如您所看到的,对于每个模型,我必须创建一个具有相同结构的父级,它只会改变子级。这个事实使我用于模型的类加倍。我想问是否有更好的方法来避免所有这些课程。

我不想使用内部类。我在想那些像这样完成 JSON 的人一定有他们这样做的原因,也是一种使解析更容易的方法。

通常我是用来解析这种JSON结构的:

{
  "data": {
    "name": "Start",
    "pid": "1",
    "position": {
      "x": "31",
      "y": "330"
    }
  }
}

如果我遵循上面的解决方案,这里会更容易。

编辑

也欢迎 Kotlin 中的任何解决方案

编辑 2

Kotlin 解决方案here

【问题讨论】:

  • 我在这里的评论是让类还不错,它使您的代码更有条理,但是如果您想要简单的方法来序列化和反序列化您的类,我可以建议一个解决方案。
  • 而且我认为如果你愿意,也可以避免创建这些数据类
  • 欢迎任何解决方案 :)
  • 你的问题是..?似乎您想跳过 datametadata 字段的映射,但仍然获取 data 属性下的值,就好像给定的 JSON 只是 {"name":"Start","pid":"1","position":{"x":"31","y":"330"}}
  • 不,我的想法是找到一个解决方案,避免我为每个模型创建一个额外的类(包含数据和元数据),但我想拥有 JSON 提供的所有数据。在我看来,这听起来像是我在做重复的代码,这样我的课程数量就翻了一番。

标签: java android json parsing kotlin


【解决方案1】:

我认为您的要求是不可能的。如果有解决方案,那么它只会创建与您正在做的事情几乎相同的中间类。

在 Kotlin 中,我会这样做。甚至可以将其放入一个 .kt 文件中:

data class MResponse(@SerializedName("data") val user: User,
                     val metadata: String)

data class User(val name: String,
                val pid: String,
                @SerializedName("position") val positionData: PositionData)


data class PositionData(@SerializedName("position") val position: Position,
                        val metadata: String)

data class Position(val x: String, val y: String)

【讨论】:

    【解决方案2】:

    好吧,我认为我要求的解决方案很简单,只是一开始我不知道。

    基于Retrofit 的源代码和关于Java generics 的其他一些相关答案,这是我的问题的答案:

    public class DataResponse<T, R> {
    
        public T data;
    
        @SerializedName("meta")
        public R metadata;
    }
    

    这是我如何使用它的示例:

    Observable<DataResponse<User, BaseMeta>> getUser()
    

    对我来说,这就是解决方案。如果有更好的解决方案,我愿意接受。

    【讨论】:

      猜你喜欢
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多