【问题标题】:Converting a json file to a Java map, using a custom class type使用自定义类类型将 json 文件转换为 Java 映射
【发布时间】:2020-01-03 13:43:06
【问题描述】:

所以我目前正在尝试将 json 文件转换为 java 地图。我只是使用以下代码,它可以正常工作:

ObjectMapper mapper = new ObjectMapper();
try {
    Map<String, Object> map = mapper.readValue(new File(
        "res/cache.json"), new TypeReference<Map<String, Object>>() {
    });

} catch (Exception e) {
    e.printStackTrace();
}

但是,问题是我不希望地图的类型为Map&lt;String, Object&gt;,而是Map&lt;String, NodeType&gt;,我在其中创建了一个新的静态类,如下所示。

static class NodeType {
    // A map of all the nodes, for example '{0001 : node, 0002 : anotherNode}'
    public Map<String, Node> nodes; //Note: Node is another static class containing a map of values.

    public NodeType() {
        nodes = new HashMap<>();
    }
}

我的解决方案是将new TypeReference&lt;Map&lt;String, Object&gt;&gt; 替换为new TypeReference&lt;Map&lt;String, NodeType&gt;&gt;,但我目前收到一个错误,即json 和类的结构不完全匹配。为了尝试解释,该类将每个变量作为 json 中的键/值,然后将映射作为另一个键/值映射。 有谁知道我如何“扁平化” NodeType 类以使两个结构匹配。

谢谢。

Json 文件内容:

{
  "areas" : {
    "0001" : {
      "lightsOn" : false,
      "volume" : 30,
      "musicPlaying" : true,
      "videoPlaying" : false
    },
    "0002" : {
      "lightsOn" : false,
      "volume" : 15,
      "musicPlaying" : true,
      "videoPlaying" : false
    },
    "0003" : {
      "lightsOn" : true,
      "volume" : 60,
      "musicPlaying" : true,
      "videoPlaying" : false
    }
  },
  ...
}

补充一点,当我通过 Object Mapper 解析 NodeType 类时,我得到了这个:

{
  "nodes" : {
    "0002" : {
      "states" : {
        "volume" : 15,
        "musicPlaying" : true,
        "lightsOn" : false,
        "videoPlaying" : false
      }
    },
    "0003" : {
      "states" : {
        "volume" : 60,
        "musicPlaying" : true,
        "lightsOn" : true,
        "videoPlaying" : false
      }
    },
    "0001" : {
      "states" : {
        "volume" : 30,
        "musicPlaying" : true,
        "lightsOn" : false,
        "videoPlaying" : false
      }
    }
  }
}

编辑:我觉得我可能在本教程的正确轨道上 - https://www.baeldung.com/jackson-map

【问题讨论】:

  • 在我看来,您要做的仍然是尝试将JSON字符串转换为嵌套的Map。那么new TypeReference&lt;Map&lt;String, Object&gt;&gt; 有什么问题呢?

标签: java json dictionary


【解决方案1】:

要么创建与文件匹配的 JSON 表示,要么手动(反)序列化 JSON。

JSON 表示可能类似于

public class JSONContent {

    private Map<String, AreasContent> areas;
}

public class AreasContent  {

    private boolean lightsOn;
    private int volume;
    private boolean musicPlaying;
    private boolean videoPlaying;
}

用法:

JSONContent jsonContent = mapper.readValue(new File("res/cache.json"), JSONContent.class);

编辑:

关于您的评论,您可以尝试类似

public class JSONContent {

    private Map<String, Map<String, Object>> areas;
}

用法同上。

【讨论】:

  • 感谢您的回复,但不幸的是,我认为这种方法对我来说不太适用,因为程序运行的持续时间正在从 json 添加/编辑/删除数据。
  • 为什么在 JSON 中添加/编辑/删除数据会成为 JSON 解析的问题?
  • 如在程序运行时,可以将新的键/值对添加到 AreasContent(),例如 powerOn。因此,您将无法在“内容”类中拥有特定和固定的变量,而是一个可以添加到的地图。
  • 我不认为你想要什么是立即可能的 - 一方面,NodeType 应该是一个 Map,另一方面你希望 NodeType 是一个不同的 Java 对象 - 决定两者之一可能性。
  • 是的,我同意你的看法——这可能是一种方法。我只是觉得一旦你开始在类内的映射中嵌套映射,代码就会开始变得混乱和混乱。不过我会试一试,谢谢:)
猜你喜欢
  • 1970-01-01
  • 2021-06-05
  • 2022-01-22
  • 1970-01-01
  • 2017-11-29
  • 1970-01-01
  • 2018-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多