¿Cómo analizar una cadena JSON en JsonNode en Jackson?

3 minutos de lectura

avatar de usuario
fadmaa

Debería ser tan simple, pero no puedo encontrarlo después de intentarlo durante una hora.

Necesito obtener una cadena JSON, por ejemplo, {"k1":v1,"k2":v2}analizado como un JsonNode.

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

da

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

  • #embarrasing — no. Si las cosas simples no son simples, entonces el diseñador de API ha fallado, no usted.

    – jamesfisher

    15/08/2014 a las 17:05

  • Respuesta de @StaxMan en código: JsonFactory factory = new MappingJsonFactory();

    –Juan Rojas

    8 de mayo de 2020 a las 6:55


avatar de usuario
slashnick

Una ligera variación en la respuesta de Richards pero readTree puede tomar una cadena para que pueda simplificarla a:

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

  • Para cualquiera que necesite un ObjectNode preferible a JsonNode usar mapper.valueToTree("{\"k1\":\"v1\"}")

    –Matthew Herbst

    18 de febrero de 2015 a las 22:14

  • @MatthewHerbst En 2.5.1, esto crea un nuevo nodo de texto con la cadena “{\”k1\”:\”v1\”}” en lugar de analizarlo como JSON.

    – minexew

    26 de abril de 2016 a las 15:42

avatar de usuario
Richard Fearn

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

Se puede encontrar más documentación sobre la creación de analizadores. aquí.

  • ¿Es posible tomar JsonNode, modificarlo un poco y luego llamar a mapper.readValue (nodo, clase); y salir de una clase?

    – Benathon

    26 de julio de 2012 a las 3:56

  • Sí. Incluso hay un alias para eso, mapper.treeToValue(). Pero readValue() también funciona

    – StaxMan

    4 de julio de 2013 a las 18:19

Una tercera variante:

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

  • ¿Qué te trajo aquí pasar JsonNode.class?

    – David

    24/10/2013 a las 18:10

  • @David: Nada, así que la variante de slashnick es obviamente mejor si solo quieres un JsonNode. Sin embargo, por lo general no desea un JsonNodeasí que quería mostrar cómo decirle a Jackson qué tipo de valor quieres de ti.

    – qerub

    16 de noviembre de 2013 a las 18:33

  • para mi, pasando JsonNode aparentemente era necesario para evitar que Jackson lo deserializara como otra cosa, lo que habría fallado.

    –Cory Klein

    26 de febrero de 2015 a las 3:44

avatar de usuario
StaxMan

La respuesta de Richard es correcta. Alternativamente, también puede crear un MappingJsonFactory (en org.codehaus.jackson.map) que sabe dónde encontrar ObjectMapper. El error que obtuviste fue porque el regular JsonFactory (de core paquete) no tiene ninguna dependencia con ObjectMapper (que está en el mapper paquete).

Pero por lo general solo usas ObjectMapper y no te preocupes por JsonParser u otros componentes de bajo nivel: solo serán necesarios si desea vincular datos a partes de la transmisión o realizar un manejo de bajo nivel.

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

avatar de usuario
manuel ortiz

Nuevo enfoque a la vieja pregunta. Una solución que funciona desde java 9+

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

es más legible y mantenible para objetos complejos. 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);

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad