【问题标题】:json parsing problemsjson解析问题
【发布时间】:2011-07-04 21:29:49
【问题描述】:
 data: [
        { 
         type: "earnings" 
         info: { 
                earnings: 45.6 
                dividends: 4052.94 
                gains: 0 
                expenses: 3935.24 
                shares_bought: 0 
                shares_bought_user_count: 0 
                shares_sold: 0 
                shares_sold_user_count: 0 
               } 
         created: "2011-07-04 11:46:17" 
        }
        { 
         type: "mentions" 
         info: [ 
                { 
                 type_id: "twitter" 
                 mentioner_ticker: "LOANS" 
                 mentioner_full_name: "ERICK STROBEL" 
                } 
               ] 
         created: "2011-06-10 23:03:02" 
        }
       ]

这是我的问题:就像你可以看到“信息”在每一个中都不同,一个是 json 对象,一个是 json 数组,我通常选择 Gson 来获取数据,但使用 Gson 我们可以'不要做这种事。我怎样才能让它工作?

【问题讨论】:

  • 问题是你不知道你从 data 读取的对象的类型?

标签: java android arrays json syntax


【解决方案1】:

如果你想使用 Gson,那么为了处理相同的 JSON 元素值有时是数组有时是对象的问题,需要自定义反序列化处理。我在Parsing JSON with GSON, object sometimes contains list sometimes contains object 帖子中发布了一个示例。

如果“info”元素对象具有基于类型的不同元素,并且您希望多态反序列化行为反序列化为正确类型的对象,那么您还需要使用 Gson 实现自定义反序列化处理。如何做到这一点已在 StackOverflow.com 的其他帖子中介绍过。我在Can I instantiate a superclass and have a particular subclass be instantiated based on the parameters supplied 线程中发布了指向四个不同此类问题和答案(一些带有代码示例)的链接。在这个线程中,要反序列化的 JSON 对象的特定结构与我刚刚链接的示例不同,因为指示类型的元素在要反序列化的对象的外部,但是如果您可以理解其他示例,则处理问题这里应该很容易。

【讨论】:

    【解决方案2】:

    key 和 value 都必须在引号内,并且需要用逗号分隔定义:

    { 
      "key0": "value0", 
      "key1": "value1", 
      "key2": [ "value2_0", "value2_1" ] 
    }
    

    这应该可以解决问题!

    【讨论】:

    • 虽然这确实表明了对有效 JSON 的更正,但它并没有解决 OP 询问的问题。
    【解决方案3】:

    info 对象应该与每个type 的类型相同。 所以先检查type。伪代码:

    if (data.get('type').equals("mentions") {
        json_arr = data.get('info');
    }
    else if (data.get('type').equals("earnings") {
        json_obj = data.get('info');
    }
    

    我不确定这是否有帮助,因为我不确定我是否理解这个问题。

    【讨论】:

    • 哈哈,这个伪代码就像 JS/Jquery 和 c 一样的命名变量,对于一个 java 问题:P
    【解决方案4】:

    仅使用 android 中可用的 org.json 类:http://developer.android.com/reference/org/json/package-summary.html

    您将获得一个可以遍历的动态结构,而不受强类型的限制.....

    这不是 Java 中“通常”的做事方式(默认为强类型),但恕我直言,即使在 Java 中,在许多情况下也可以进行一些动态处理。灵活性更好,但要付出的代价是缺乏编译时类型验证......在很多情况下都可以。

    【讨论】:

    • 不是真的..强类型有其优点,也有缺点......我实际上在Java强类型的编译时正确性和python、groovy等的动态优势之间左右为难而且我很容易找到两者中的任何一个更好的情况......所以我在不同的情况下使用这两种方法......根据问题调整我的工具而不是相反。
    • 我的评论是半开玩笑而不是严肃。并不是说我同意营地的“动态”方面。
    • 嗯,即使是幽默感也有它无限的优势;)
    【解决方案5】:

    如果更改库是一个选项,您可以看看 Jackson,它的 Simple Data Binding 模式应该允许您像您描述的那样反序列化对象。文档中可能非常重要的一部分是this,您的示例已经需要JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES 才能工作...

    对 Bruce 的澄清:是的,在 Jackson 的完整数据绑定模式下,但不是在简单数据绑定模式下。这是简单的数据绑定:

    public static void main(String[] args) throws IOException {
        File src = new File("test.json");
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(JsonParser.Feature. ALLOW_UNQUOTED_FIELD_NAMES, true);
        mapper.configure(JsonParser.Feature.ALLOW_COMMENTS,true);
    
        Object root = mapper.readValue(src, Object.class);
        Map<?,?> rootAsMap = mapper.readValue(src, Map.class);
        System.out.println(rootAsMap);
    }
    

    使用 OP 的经过微调的 JSON 数据示例给出:

    {data=[{type=earnings, info={earnings=45.6, dividends=4052.94, gains=0,
    expenses=3935.24, shares_bought=0, shares_bought_user_count=0, shares_sold=0,
    shares_sold_user_count=0}, created=2011-07-04 11:46:17}, {type=mentions,
    info=[{type_id=twitter, mentioner_ticker=LOANS, mentioner_full_name=ERICK STROBEL}],
    created=2011-06-10 23:03:02}]}
    

    好的,需要一些手动编码来将此地图连接到原始数据,但通常少即是多,这样的映射代码,非常简单的优点是以后非常容易阅读/维护。

    【讨论】:

    • 所描述的问题涉及 info 元素值有时是一个对象,有时是一个数组,并且数组中的对象与它的对应对象(不在数组中)具有不同的元素。 Jackson 的下一个版本将具有自动展开单个元素数组的功能,这可能适用于这种特殊情况,但仍然需要解决不同对象结构/元素的问题。为此,Jackson 的多态反序列化功能可能适用。
    • @Bruce 上次我玩杰克逊的多态反序列化仍然很可怕——也许我应该再试一次。同时,我还添加了一个代码示例,它使用简单的数据绑定来反序列化 OP 的示例数据...
    • 对象根 = mapper.readValue(src, Object.class); ——这是杰克逊的一大优点。它会将几乎所有内容反序列化为仅由 Java SE 类型组成的 Java 数据结构。只需一行代码。我还没有看到另一个可以做到这一点的 Java-to/from-JSON 库。
    • "上次我在 Jackson 中使用多态反序列化仍然很可怕" 现在我发现它很容易。我在goo.gl/nVKBZ 发布了一些示例
    猜你喜欢
    • 1970-01-01
    • 2015-10-29
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多