【问题标题】:converting json string to object through GSON通过 GSON 将 json 字符串转换为对象
【发布时间】:2017-08-11 09:55:30
【问题描述】:

我正在尝试将 json 字符串解析为 java 对象,但我不确定对象层次结构。

下面是json字符串

{  
   "TABLE_Detail":{  
      "1":{  
         "TABLE":"table1",
         "RUN_DATE":"20170313",
         "SEQ_NUM":"123",
         "START_TIME":"20170313133144",
         "END_TIME":"20170313133655"
      },
      "2":{  
         "TABLE":"table2",
         "RUN_DATE":"20170313",
         "SEQ_NUM":"123",
         "START_TIME":"20170313133142",
         "END_TIME":"20170313133723"
      }
   }
}

这里的数字12 是动态的,可以上升到任何数字,我尝试创建一个外部对象,并将键字符串类型的映射和值作为对象 TableData。具有变量名称TABLE_Detail 的映射。但 TableData 对象始终为空。 TableData 对象包含所有变量。

请帮助我了解如何将此 json 字符串转换为对象。

【问题讨论】:

  • 您没有显示任何代码。我们应该怎么知道TableData 是什么?

标签: java json string rest gson


【解决方案1】:

将 1 更改为 table1,将 2 更改为 table2:

public class TableDetails {
    private TableData table1;

    private TableData table2;

    public TableDetails(){

    }

    // getter and setter
}

如果将json格式修改为“Koen Van Looveren”提到:

public class TableDetails {
    List<TableData> tables;

    public TableDetails() {
    }
    // getter and setter
}

表类: 表.java:

public class TableData {
    private String table;

    private String run_date;

    private String seq_num;

    private String start_time;

    private String end_time;

    public TableData() {
    }

    // getter and setter
}

【讨论】:

  • 您好,响应来自较旧的服务,恐怕他们可能不会更改响应结构。有没有一种方法可以从我这边如何按原样消费响应。请提出建议。
  • 如果不改json格式,可以使用TableDetails的第一种形式,我只是把变量名1改成table1,2改成table2。但是1和2是同一个对象类型,最好用一个列表。
【解决方案2】:

在使用 Gson 时,对于这种令人痛苦的 json 结构,您有两种选择。

  1. 使用 Gson 解析 json 作为 Map 并编写一些类访问返回的 Map。此模式仅适用于访问数据!

    //usage
    TableDetails details=new TableDetails(gson.fromJson(json, Map.class));
    
    //classes
    class TableDetails {
        private Map<String, Map> context;
    
        public TableDetails(Map root) {
            this.context = (Map<String, Map>) root.get("TABLE_Detail");
        }
    
        public int size() {
            return context.size();
        }
    
    
        public Table get(String key) {
            return new Table(context.get(key));
        }
    }
    
    class Table {
    
        private Map context;
    
        public Table(Map context) {
            this.context = context;
        }
    
        public String getName() {
            return get("TABLE");
        }
    
        private <T> T get(String name) {
            return (T) context.get(name);
        }
        ...
    }
    
  2. 编写您自己的 Gson TypeAdapter,但这种方式可能更复杂。如果您对编写自定义 TypeAdapter 感兴趣,有一个我为提取 json root 编写的演示。gson-enclosing-plugin

【讨论】:

    【解决方案3】:

    您可以尝试将其反序列化为Map&lt;String, Map&lt;String, TableData&gt;&gt;Map&lt;String, TableData&gt; 不起作用的原因是伪数组被包装在另一个对象中。

    以下示例将响应转换为List&lt;TableData&gt;

    public List<TableData> deserialize(String json) {
        return Gson().<Map<String, Map<String, TableData>>>fromJson(json, new TypeToken<Map<String, Map<String, TableData>>>(){}.getType())
            .values().iterator().next()
            .entrySet().stream()
            .sorted(Comparator.comparingInt(e -> Integer.parseInt(e.getKey())))
            .map(Map.Entry::getValue)
            .collect(Collectors.toList());
    }
    

    【讨论】:

      【解决方案4】:

      我正在寻找解决方案,并且遇到了解决方案有效的网站之一。我想归功于以下网站。感谢大家的支持。

      我能够映射动态值 1、2,因为映射键和值使用 @SerializedName gson 注解对应映射到 TableData 对象属性。

      http://findnerd.com/list/view/Parse-Json-Object-with-dynamic-keys-using-Gson-/24094/

      【讨论】:

        【解决方案5】:

        在 json 中使用数组时,您需要使用 [ 打开和 ] 关闭

        {
          "TABLE_Detail": [
            {
              "TABLE": "table1",
              "RUN_DATE": "20170313",
              "SEQ_NUM": "123",
              "START_TIME": "20170313133144",
              "END_TIME": "20170313133655"
            },
            {
              "TABLE": "table2",
              "RUN_DATE": "20170313",
              "SEQ_NUM": "123",
              "START_TIME": "20170313133142",
              "END_TIME": "20170313133723"
            }
          ]
        }
        

        【讨论】:

        • 嗨,不,json 响应不包含数组括号。响应与我在查询中给出的相同。
        • 为什么要投反对票?使用动态列表将始终解析为此 json 结构。否则你没有使用动态列表。
        猜你喜欢
        • 2018-01-20
        • 2021-10-04
        • 1970-01-01
        • 2013-05-19
        • 1970-01-01
        • 2017-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多