Java/Kotlin JSON 解析改进

Posted

技术标签:

【中文标题】Java/Kotlin JSON 解析改进【英文标题】:Java/Kotlin JSON parsing improvement 【发布时间】: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 提供的所有数据。在我看来,这听起来像是我在做重复的代码,这样我的课程数量就翻了一番。 【参考方案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()

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

【讨论】:

以上是关于Java/Kotlin JSON 解析改进的主要内容,如果未能解决你的问题,请参考以下文章

优雅地把Html解析为Java/Kotlin实体对象

优雅地把Html解析为Java/Kotlin实体对象

优雅地把Html解析为Java/Kotlin实体对象

如何读取将作为 MultipartFile 参数传递的 SQLite 文件? (在 java/kotlin 中)

Kotlin 与 Java 相互调用

Kotlin使用率达35%,Java要退位了?