如何使用Jackson将JSON字符串解析为JsonNode?

269

看起来很简单,但我试了一个小时仍然找不到。

我需要将一个JSON字符串,例如{"k1":v1,"k2":v2},解析为一个JsonNode对象。

JsonFactory factory = new JsonFactory();
JsonParser jp = factory.createJsonParser("{\"k1\":\"v1\"}");
JsonNode actualObj = jp.readValueAsTree();

给出

java.lang.IllegalStateException: 解析器未定义ObjectCodec,无法将JSON反序列化为JsonNode树


66
“#embarrassing”-- 不对。如果简单的事情变得复杂,那是API设计者失败了,而不是你失败了。 - jameshfisher
1
@StaxMan的代码回答:JsonFactory factory = new MappingJsonFactory(); - Juan Rojas
6个回答

425
稍微变化一下Richard的回答,但是readTree可以接收字符串,因此您可以将其简化为:
ObjectMapper mapper = new ObjectMapper();
JsonNode actualObj = mapper.readTree("{\"k1\":\"v1\"}");

49
对于需要 ObjectNode 而不是 JsonNode 的任何人,可以使用 mapper.valueToTree("{\"k1\":\"v1\"}") - Matthew Herbst
8
在2.5.1中,这将创建一个包含字符串"{"k1":"v1"}"的新文本节点,而不是将其解析为JSON。 - minexew

72
您需要使用一个 ObjectMapper
ObjectMapper mapper = new ObjectMapper();
JsonFactory factory = mapper.getJsonFactory(); // since 2.1 use mapper.getFactory() instead
JsonParser jp = factory.createJsonParser("{\"k1\":\"v1\"}");
JsonNode actualObj = mapper.readTree(jp);

关于创建解析器的更多文档可以在这里找到。


能否获取JsonNode,稍作修改,然后调用mapper.readValue(node, class); 以获取一个类? - benathon
1
是的,甚至还有一个别名叫做 mapper.treeToValue()。但是 readValue() 也可以使用。 - StaxMan

32

第三种变体:

ObjectMapper mapper = new ObjectMapper();
JsonNode actualObj = mapper.readValue("{\"k1\":\"v1\"}", JsonNode.class);

在这里传递JsonNode.class实际上给你带来了什么? - David
3
@David:如果你只需要一个JsonNode,那么slashnick的变体显然更好。然而,通常你不想要一个JsonNode,所以我想展示如何告诉Jackson你想要什么类型的值。 - qerub
对我来说,传递JsonNode显然是必要的,以防止Jackson将其反序列化为其他内容 - 这将会失败。 - Cory Klein

5
Richard的回答是正确的。另外,您还可以创建一个MappingJsonFactory(在org.codehaus.jackson.map中),它知道在哪里找到ObjectMapper。您收到的错误是因为常规的JsonFactory(来自core包)没有依赖于ObjectMapper(它在mapper包中)。
但通常您只需要使用ObjectMapper而不必担心JsonParser或其他低级组件--如果您想要数据绑定流的部分或进行低级处理,则只需要这些组件。

5
import com.github.fge.jackson.JsonLoader;
JsonLoader.fromString("{\"k1\":\"v1\"}")
== JsonNode = {"k1":"v1"}

4

对老问题的新方法。一种适用于Java 9及以上版本的解决方案。

ObjectNode agencyNode = new ObjectMapper().valueToTree(Map.of("key", "value"));

更适合复杂对象的可读性和可维护性。例如:
Map<String, Object> agencyMap = Map.of(
        "name", "Agencia Prueba",
        "phone1", "1198788373",
        "address", "Larrea 45 e/ calligaris y paris",
        "number", 267,
        "enable", true,
        "location", Map.of("id", 54),
        "responsible", Set.of(Map.of("id", 405)),
        "sellers", List.of(Map.of("id", 605))
);
ObjectNode agencyNode = new ObjectMapper().valueToTree(agencyMap);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接