如何在杰克逊的JsonNode中解析JSON字符串?


231

它应该是如此简单,但是在尝试一个小时的尴尬之后,我只是找不到它。

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

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

java.lang.IllegalStateException: No ObjectCodec defined for the parser, can not deserialize JSON into JsonNode tree


54
#embarrasing - 不。如果简单的事情不简单,那么API设计器就会失败,而不是您。
jameshfisher 2014年

@StaxMan在代码中的答案:JsonFactory factory = new MappingJsonFactory();
胡安·罗哈斯

Answers:


371

理查兹的答案略有变化,但readTree可以使用字符串,因此可以将其简化为:

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

44
对于需要使用ObjectNode而不是JsonNode使用的任何人mapper.valueToTree("{\"k1\":\"v1\"}")
Matthew Herbst

5
@MatthewHerbst在2.5.1中,这将创建一个新的文本节点,其字符串为“ {\” k1 \“:\” v1 \“}”,而不是将其解析为JSON。
minexew '16

69

您需要使用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); 去上课?
portforwardpodcast 2012年

1
是。甚至还有一个别名mapper.treeToValue()。而且readValue()可行。
StaxMan

链接似乎已断开
玛娜娜

28

第三种变体:

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

传递JsonNode.class实际上使您到达这里是什么?
大卫,

3
@David:没什么,所以如果您只想要slashnick的变体,显然更好JsonNode。但是,您通常不想要JsonNode,所以我想展示如何告诉杰克逊您想要什么样的价值。
qerub

对我而言,JsonNode显然有必要通过,以防止杰克逊将其反序列化为其他内容-否则会失败。
科里·克莱恩

5

理查德的答案是正确的。或者,您也可以创建一个MappingJsonFactory(in org.codehaus.jackson.map)知道在哪里可以找到ObjectMapper。你得到的错误是因为正规JsonFactory(从core包装)没有依赖关系ObjectMapper(这是在mapper包)。

但是通常您只使用ObjectMapper而不用担心JsonParser其他低级组件-如果您想对流的一部分数据进行绑定或进行低级处理,将只需要它们。


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

0

解决旧问题的新方法。适用于Java 9+的解决方案

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

对于复杂对象更具可读性和可维护性。j

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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.