【问题标题】:How to deserialize this dynamic valued JSON?如何反序列化这个动态值的 JSON?
【发布时间】:2018-03-30 07:36:32
【问题描述】:

我想反序列化下面的 JSON(原来有大约 100 个Exchanges 带有动态值):

{
  "Exchange1": {
    "EUR": [
      "CNY",
      "USD"
    ],
    "INR": [
      "USD",
      "CNY"
    ]
  },
  "Exchange2": {
    "BRL": [
      "EUR",
      "USD",
      "INR"
    ],
    "JPY": [
      "USD",
      "EUR",
      "CNY"
    ]
  },
  ....
}

我正在使用http://www.jsonschema2pojo.org/,但它正在生成一个采用文字值(“Exchange1”、“EUR”等)的 Java 类,而无论动态字符串值是什么,我都需要对其进行迭代:


如何用 Java 描述这个 JSON?

【问题讨论】:

    标签: java json gson retrofit2


    【解决方案1】:

    你不能在这里使用 POJO(在理智的意义上),但是人们倾向于使用 POJO 生成器,即使对动态对象也不做提前分析。 “动态”对象通常应该使用java.util.Map(有序实现)映射+唯一值可以使用java.util.Set(有序实现)映射。 因此,如果您有货币的自定义枚举,请说类似

    enum Currency {
    
        BRL,
        CNY,
        EUR,
        INR,
        JPY,
        USD,
    
    }
    

    那么您可以轻松地定义映射,而无需任何看起来在这里根本不适用的 POJO:

    private static final Type exchangesType = new TypeToken<Map<String, Map<Currency, Set<Currency>>>>() {
    }.getType();
    
    final Map<String, Map<Currency, Set<Currency>>> exchanges = gson.fromJson(jsonReader, exchangesType);
    System.out.println(exchanges);
    

    所以微不足道的toString() 输出将如下:

    {Exchange1={EUR=[CNY, USD], INR=[USD, CNY]}, Exchange2={BRL=[EUR, USD, INR], JPY=[USD, EUR, CNY]}}

    如果您不喜欢使用 Currency 枚举的想法(您必须始终通过重新编译等保持最新状态),那么您可以简单地将货币标记声明为 java.lang.String 并获得相同的结果:

    private static final Type exchangesType = new TypeToken<Map<String, Map<String, Set<String>>>>() {
    }.getType();
    
    final Map<String, Map<String, Set<String>>> exchanges = gson.fromJson(jsonReader, exchangesType);
    System.out.println(exchanges);
    

    【讨论】:

    • Map&lt;String, Map&lt;String, Set&lt;String&gt;&gt;&gt; 非常适合我的情况,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-10-01
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 2015-06-03
    • 2019-12-20
    相关资源
    最近更新 更多