251 votes

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

Cela devrait être si simple, mais je n'arrive pas à le trouver après avoir essayé pendant une heure.

J'ai besoin d'obtenir une chaîne JSON, par exemple, {"k1":v1,"k2":v2} qui est analysé comme un 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

64 votes

#embarrasing -- non. Si les choses simples ne sont pas simples, c'est le concepteur de l'API qui a échoué, pas vous.

1 votes

La réponse de @StaxMan en code : JsonFactory factory = new MappingJsonFactory() ;

401voto

slashnick Points 9773

Une légère variation de la réponse de Richards mais readTree peut prendre une chaîne de caractères, ce qui permet de le simplifier :

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

47 votes

Pour tous ceux qui ont besoin d'un ObjectNode plutôt qu'un JsonNode utiliser mapper.valueToTree("{\"k1\":\"v1\"}")

8 votes

@MatthewHerbst Dans la version 2.5.1, cela crée un nouveau nœud de texte avec la chaîne "{\"k1\":\"v1\"}" au lieu de l'analyser en JSON.

71voto

Richard Fearn Points 11631

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);

Une documentation supplémentaire sur la création d'analyseurs syntaxiques est disponible aquí .

0 votes

Est-il possible de prendre le JsonNode, de le modifier un peu, puis d'appeler mapper.readValue(node, class) ; et d'obtenir une classe ?

1 votes

Oui. Il y a même un alias pour ça, mapper.treeToValue() . Mais readValue() fonctionne également.

0 votes

Le lien semble être cassé

31voto

qerub Points 1099

Une troisième variante :

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

0 votes

Qu'est-ce que le passage dans JsonNode.class vous a apporté ici ?

3 votes

@David : Rien, donc la variante de Slashnick est manifestement meilleure si vous voulez juste une JsonNode . Cependant, vous ne voulez généralement pas un JsonNode Je voulais donc montrer comment dire à Jackson quel type de valeur vous voulez.

0 votes

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

5voto

StaxMan Points 34626

La réponse de Richard est correcte. Vous pouvez également créer un MappingJsonFactory (en org.codehaus.jackson.map ) qui sait où trouver ObjectMapper . L'erreur que vous avez eue est due au fait que l'ordinaire JsonFactory (de core ) ne dépend pas de ObjectMapper (qui se trouve dans le mapper paquet).

Mais en général, vous utilisez simplement ObjectMapper et ne vous inquiétez pas pour JsonParser ou d'autres composants de bas niveau -- ils seront juste nécessaires si vous voulez lier des parties du flux de données, ou faire de la manipulation de bas niveau.

3voto

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X