Comment analyser une chaîne JSON en JsonNode à Jackson?


231

Cela devrait être si simple, mais je ne le trouve pas après avoir essayé pendant une heure #embarrasing.

J'ai besoin d'obtenir une chaîne JSON, par exemple {"k1":v1,"k2":v2}, analysée en tant que JsonNode.

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

donne

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


54
#embarrasing-- Nan. Si les choses simples ne sont pas simples, c'est le concepteur d'API qui a échoué, pas vous.
jameshfisher

@ Réponse de StaxMan dans le code: JsonFactory factory = new MappingJsonFactory ();
Juan Rojas

Réponses:


371

Une légère variation sur la réponse de Richards mais readTreepeut prendre une chaîne afin que vous puissiez la simplifier pour:

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

44
Pour tous ceux qui ont besoin ObjectNoded'une JsonNodeutilisation plutôt que d'une utilisationmapper.valueToTree("{\"k1\":\"v1\"}")
Matthew Herbst

5
@MatthewHerbst Dans 2.5.1, cela crée un nouveau nœud de texte avec la chaîne "{\" k1 \ ": \" v1 \ "}" plutôt que de l'analyser en JSON.
minexew

69

Vous devez utiliser un 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);

Vous trouverez plus de documentation sur la création d'analyseurs syntaxiques ici .


Est-il possible de prendre le JsonNode, de le modifier un peu, puis d'appeler mapper.readValue (nœud, classe); et sortir un cours?
portforwardpodcast

1
Oui. Il y a même un alias pour ça mapper.treeToValue(),. Mais readValue()ça marche aussi.
StaxMan

Le lien semble rompu
manuna

28

Une troisième variante:

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

Qu'est-ce qui vous a amené à passer dans JsonNode.class?
David

3
@David: Rien, donc la variante de slashnick est évidemment meilleure si vous voulez juste un JsonNode. Cependant, vous n'en voulez généralement pas JsonNode, alors je voulais montrer comment dire à Jackson quel genre de valeur vous voulez.
qerub

Pour moi, le passage JsonNodeétait apparemment nécessaire pour empêcher Jackson de le désérialiser comme autre chose - ce qui aurait échoué.
Cory Klein

5

La réponse de Richard est correcte. Alternativement, vous pouvez également créer un MappingJsonFactory(in org.codehaus.jackson.map) qui sait où trouver ObjectMapper. L'erreur que vous avez eue était parce que le régulier JsonFactory(du corepackage) n'a aucune dépendance à ObjectMapper(qui est dans le mapperpackage).

Mais généralement, vous n'utilisez ObjectMapperet ne vous inquiétez pas pour d' JsonParserautres composants de bas niveau - ils seront simplement nécessaires si vous souhaitez lier des parties de flux ou effectuer une manipulation de bas niveau.


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

0

Nouvelle approche de l'ancienne question. Une solution qui fonctionne à partir de Java 9+

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

est plus lisible et plus facile à gérer pour les objets complexes. Ej

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);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.