【问题标题】:What is the proper way of handling multiple JSON Objects with Retrofit 2?使用 Retrofit 2 处理多个 JSON 对象的正确方法是什么?
【发布时间】:2019-05-12 19:05:33
【问题描述】:

我正在尝试使用 Retrofit 2 为我的 Android 项目解析 JSON URL,但我有一个问题。在我的 URL 中,JSON 如下所示:

{  
"channel0":{  
  "song":"Crush",
  "artist":"Jennifer Paige",
  "duration":"180",
  "playedat":"1545065265",
  "image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/8eecc92227fcbb09b43472f000df74e1.png"
},
"channel1":{  
  "song":"Reasons Why",
  "artist":"Brand New Immortals",
  "duration":"180",
  "playedat":"1545065371",
  "image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/c059afda95dd35354af26cf72e5deab4.png"
},
"channel2":{  
  "song":"Dance Me To The End Of Love",
  "artist":"Leonard Cohen",
  "duration":"300",
  "playedat":"1545065181",
  "image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/a368617dc7dc4716a9badb523ff6e7d4.png"
},
"channel3":{  
  "song":"4 Minutes",
  "artist":"Madonna",
  "duration":"180",
  "playedat":"1545065300",
  "image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/1dcefc6496be4155a00f919dcbb54f77.png"
},
"channel4":{  
  "song":"Mothers, Sisters, Daughters",
  "artist":"Voxtrot",
  "duration":"180",
  "playedat":"1545065257",
  "image_extralarge":"https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/5861b97231bd4ffe9218dfcacc27d68a.png"
}
}

当我使用 POJO 时,它会为每个通道创建多个类。那么处理这个 JSON URL 的正确方法是什么?

【问题讨论】:

  • 在我看来,这是 API 的错误。他们应该返回一个通道数组,在通道对象上有一个 ID,并删除变量键名。有很多方法可以处理它,但重新格式化响应是 IMO 的“正确”方式。
  • 本站的代码应该写出来。这使我们可以更轻松地帮助您进行调试。
  • 请不要张贴文字截图。任何文本,包括代码、错误或 JSON,都需要作为文本,而不是屏幕截图。
  • @meagar 将其更改为文本。

标签: java android json retrofit2 pojo


【解决方案1】:

每个 JSON 对象也可以被视为 JSON 元素的 Map 字符串。在这种情况下,您将获得一个具有动态键名的对象,您不必尝试构建一个 Java 类来表示它。你可以改用Map<String, Object>

在这种情况下,您知道每个值都是一首歌曲,因此您可以比Object 更具体一点。

首先定义例如一个 Song 类来保存内部元素:

public class Song {

    public String song;
    public String artist;
    ...
}

然后你会打电话并循环结果:

Call<Map<String, Song>> call = ...
call.enqueue(new Callback<Map<String, Song>>() {

    @Override
    public void onResponse(Response<Map<String, Song>> response) {
        Map<String, Song> body = response.body();
        for (Song song : body.values()) {
            // your code here
        }
    }

    @Override
    public void onFailure(Throwable t) {
        // TODO
    }
});

如果出于某种原因需要,您甚至可以将其变成歌曲列表:

List<Song> songs = new ArrayList<>(body.values());

【讨论】:

  • 当我使用'retrofit2.Call> call =restInterface.getChannels();'这一行时我收到不兼容的类型错误,它变成了'retrofit2.Call> call =restInterface.getChannels();'作为 Android Studio 的自动解决方案。
【解决方案2】:

首先:这不叫 JSON URL……它是简单的 JSON,如果你愿意,也可以是 JSON 数据……URL 和 JSON 是两个完全独立的东西

第二:不清楚你说的是什么意思:

当我使用 POJO 时,它会为每个通道创建多个类。所以 处理这个 JSON URL 的正确方法是什么?

如果您从任何 JSON 到 POJO 工具生成 Java 类,这是一种正常行为,因为没有工具可以猜测 channel2channel3 相同,因为它们可能是两个完全不同的东西,没有办法知道。

正确的方法是先设计 Java 类,然后映射 JSON,而不是相反。

【讨论】:

  • 完全没有必要全部大写。
猜你喜欢
  • 1970-01-01
  • 2011-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多