【问题标题】:How to handle JSON objects wrapped into one JSON object with retrofit2?如何使用retrofit2处理包装到一个JSON对象中的JSON对象?
【发布时间】:2019-08-16 14:20:14
【问题描述】:

我想使用改造接收项目并将它们解析为 Java 列表。 但是,服务器响应不是 JSON 数组,而是包含项目的 JSON 对象。这就是改造不能仅仅将响应转换为 java 列表的原因。

响应看起来像这样:

{
    "4": {
        "key": "value",
        ...
    },
    "5": {
        ...
    }, 
    ...
}

通常,我会尝试收到这样的物品:

@GET("items")
Call<List<Item>> getItems();

但这显然不起作用,Retrofit 回复:Expected BEGIN_ARRAY but was BEGIN_OBJECT

使用改造将此对象转换为 java 列表的最佳选择是什么?

【问题讨论】:

  • 我曾经遇到过这种情况,我相信Retrofit不可能像这样完全解析响应,我们必须捕获根对象->使用GSon将其转换为String,然后解析它手动。最好的方法:告诉服务员修复它,他做了一件非常糟糕和愚蠢的事情!
  • 我认为解决方案可能类似于这篇文章:stackoverflow.com/questions/37550388/… 可能类似于 Call>>。尝试一下,祝你好运。
  • @ThinkTwiceCodeOnce 谢谢你的回答。我很确定飞利浦的服务器人员不会改变这一点。但希望他们不会再创造这样的东西。
  • @DanielSpiess:谢谢你的链接。它类似于 Fred 的回答,它解决了我的问题。

标签: java android json retrofit2


【解决方案1】:

我个人会分两步执行此操作,以避免为反序列化编写自定义适配器。

我会这样写界面:

@GET("items")
Call<Map<String, Item>> getItems();

一旦您在响应中调用 API,我只需调用 values()

需要考虑的是,由于 API 返回的是地图而不是列表,因此无法保证您生成的任何列表的顺序都是一致的。 json 标准没有为对象定义任何顺序,除非它们在 json 数组中。

【讨论】:

    【解决方案2】:

    当您说响应是 List 时,JSON 应该是一个“ARRAY”。

    例如:

    [ "a", "b" ]
    

    { 
       "xxx": [ "a", "b" ] 
    }
    

    在任何一种情况下,您要解析的对象都如下所示:

    List&lt;String&gt; 第一个。

    Thing 第二个。

    Thing 看起来像:

    class Thing {
       public List<String> xxx;
    }
    

    你正在尝试解析这个:

    {
        "4": {
            "key": "value",
            ...
        },
        "5": {
            ...
        }, 
        ...
    }
    
    

    那么根据以上信息,你认为你的响应在解析后是什么样子的? (提示:您可以尝试this Java POJO 生成器之类的东西来了解一下;)

    【讨论】:

    • 感谢您的回答。我无法更改服务器响应。这就是为什么我必须处理这个愚蠢的“对象列表”。
    • 知道了,我看到你已经得到了答案。我只是在逗你看看你能不能自己解决(它只是一个地图而不是列表)但很高兴听到你解决了它;)
    猜你喜欢
    • 2016-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-17
    • 2022-01-19
    • 1970-01-01
    相关资源
    最近更新 更多