Convertir JSON a Mapa


191

¿Cuál es la mejor manera de convertir un código JSON como este:

{ 
    "data" : 
    { 
        "field1" : "value1", 
        "field2" : "value2"
    }
}

en un mapa de Java en el que las claves son (campo1, campo2) y los valores para esos campos son (valor1, valor2).

¿Algunas ideas? ¿Debo usar Json-lib para eso? ¿O mejor si escribo mi propio analizador?


He escrito código para esto sin usar ninguna biblioteca. stackoverflow.com/questions/21720759/jsonobject-to-map/…
Vikas Gupta

Respuestas:


336

Espero que estuvieras bromeando sobre escribir tu propio analizador. :-)

Para un mapeo tan simple, la mayoría de las herramientas de http://json.org (sección java) funcionarían. Para uno de ellos (Jackson https://github.com/FasterXML/jackson-databind/#5-minute-tutorial-streaming-parser-generator ), haría:

Map<String,Object> result =
        new ObjectMapper().readValue(JSON_SOURCE, HashMap.class);

(donde JSON_SOURCE es un archivo, secuencia de entrada, lector o cadena de contenido json)


37
Además, si desea un Mapa escrito (explotando genéricos de Java), puede hacer: Map <String, MyPojo> typedMap = mapper.readValue (jsonStream, new TypeReference <Map <String, MyPojo >> () {});
obe6

55
Si trabaja con el proyecto Maven, necesitará <dependency> <groupId> com.fasterxml.jackson.core </groupId> <artifactId> jackson-databind </artifactId> <version> 2.4.4 </version> </ dependency >
LoBo

2
Y parece que Jackson se mudó desde el 09, así: Jackson data-bind
jacob.mccrumb

@ obe6 Supongo que el OP no está bromeando. ¿Puedes encontrar un solo "JSON" en cualquier parte de tu fragmento de código que no sea ese nombre de variable arbitrario? También estoy luchando por los nombres en Jackson API.
Aetherus

FWTW, mientras que la respuesta de @ obe6 es técnicamente correcto, puede utilizar la forma más corta demasiado: Map<String,Object> result = mapper.readValue(source, Map.class).
StaxMan

36

Usando la biblioteca GSON:

import com.google.gson.Gson;
import com.google.common.reflect.TypeToken;
import java.lang.reclect.Type;

Utiliza el siguiente código:

Type mapType = new TypeToken<Map<String, Map>>(){}.getType();  
Map<String, String[]> son = new Gson().fromJson(easyString, mapType);

77
Java en su mejor momento: TypeToken<Map<String, Map>>:-)
froderik

2
Con el nuevo TypeToken <Map <String, Object >> funcionará también cuando haya arrays dentro.
9ilsdx 9rvj 0lo

33

Me gusta la biblioteca de google gson .
Cuando no conoces la estructura de json. Puedes usar

JsonElement root = new JsonParser().parse(jsonString);

y luego puedes trabajar con json. por ejemplo, cómo obtener "valor1" de su gson:

String value1 = root.getAsJsonObject().get("data").getAsJsonObject().get("field1").getAsString();

19
Esto puede arrojar NullPointerExceptions 5 formas diferentes si obtiene datos inesperados.
dfraser

Puede usar .path () ahora y no arrojará un NPE
C2H50H

18

Utilice JSON lib Ej. Http://www.json.org/java/

// Assume you have a Map<String, String> in JSONObject jdata
@SuppressWarnings("unchecked")
Iterator<String> nameItr = jdata.keys();
Map<String, String> outMap = new HashMap<String, String>();
while(nameItr.hasNext()) {
    String name = nameItr.next();
    outMap.put(name, jdata.getString(name));

}

12

Mi publicación podría ser útil para otros, así que imagina que tienes un mapa con un objeto específico en valores, algo así:

{  
   "shopping_list":{  
      "996386":{  
         "id":996386,
         "label":"My 1st shopping list",
         "current":true,
         "nb_reference":6
      },
      "888540":{  
         "id":888540,
         "label":"My 2nd shopping list",
         "current":false,
         "nb_reference":2
      }
   }
}

Para analizar este archivo JSON con la biblioteca GSON, es fácil: si su proyecto está mavenizado

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.3.1</version>
</dependency>

Luego usa este fragmento:

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

//Read the JSON file
JsonElement root = new JsonParser().parse(new FileReader("/path/to/the/json/file/in/your/file/system.json"));

//Get the content of the first map
JsonObject object = root.getAsJsonObject().get("shopping_list").getAsJsonObject();

//Iterate over this map
Gson gson = new Gson();
for (Entry<String, JsonElement> entry : object.entrySet()) {
    ShoppingList shoppingList = gson.fromJson(entry.getValue(), ShoppingList.class);
    System.out.println(shoppingList.getLabel());
}

El POJO correspondiente debería ser algo así:

public class ShoppingList {

    int id;

    String label;

    boolean current;

    int nb_reference;

    //Setters & Getters !!!!!
}

Espero eso ayude !


5

De esta manera funciona como un mapa ...

JSONObject fieldsJson = new JSONObject(json);
String value = fieldsJson.getString(key);

<dependency>
    <groupId>org.codehaus.jettison</groupId>
    <artifactId>jettison</artifactId>
    <version>1.1</version>
</dependency>

1
Sí, pero debe envolver cada 'get' en try / catch debido a las excepciones JSON.
Maciej Swic

1
podrías escribir una clase JsonMap implements Map<String,Objectpara envolver JSONObject. entonces obtienes la verdadera Mapinterfaz.
Jeffrey Blattman

Por favor agregue las bibliotecas usadas.
mvermand

5

Lo hago de esta manera. Es sencillo.

import java.util.Map;
import org.json.JSONObject;
import com.google.gson.Gson;

public class Main {
    public static void main(String[] args) {
        JSONObject jsonObj = new JSONObject("{ \"f1\":\"v1\"}");
        @SuppressWarnings("unchecked")
        Map<String, String> map = new Gson().fromJson(jsonObj.toString(),Map.class);
        System.out.println(map);
    }
}

Intenté este enfoque pero no funciona ... ¿puedes responder por esto? stackoverflow.com/questions/60329223/…
Siva

3
java.lang.reflect.Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
Gson gson = new Gson();
Map<String, Object> categoryicons = gson.fromJson(json, mapType );


2

Con Google Gson 2.7 (probablemente también versiones anteriores, pero probé 2.7) es tan simple como:

Map map = gson.fromJson(json, Map.class);

Que devuelve un Mapa de tipo class com.google.gson.internal.LinkedTreeMapy funciona de forma recursiva en objetos anidados.


1

Una alternativa más es json-simple que se puede encontrar en Maven Central :

(JSONObject)JSONValue.parse(someString); //JSONObject is actually a Map.

El artefacto es de 24kbytes, no tiene otras dependencias de tiempo de ejecución.


Recibo nullde vuelta desde una simple cadena JSON donde uno de los valores es una matriz de cadenas.
isapir

1

Si está utilizando org.json, JSONObject tiene un método toMap(). Puedes hacer fácilmente:

Map<String, Object> myMap = myJsonObject.toMap();

0
import net.sf.json.JSONObject

JSONObject.fromObject(yourJsonString).toMap

0

Underscore-java biblioteca puede convertir la cadena json en un mapa hash. Soy el mantenedor del proyecto.

Ejemplo de código:

import com.github.underscore.lodash.U;
import java.util.*;

public class Main {

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        String json = "{"
            + "    \"data\" :"
            + "    {"
            + "        \"field1\" : \"value1\","
            + "        \"field2\" : \"value2\""
            + "    }"
            + "}";

       Map<String, Object> data = (Map) U.get((Map<String, Object>) U.fromJson(json), "data");
       System.out.println(data);

       // {field1=value1, field2=value2}
    }
}

0

Si necesita Java puro sin dependencias, puede usar la compilación en la API de Nashorn desde Java 8. Está en desuso en Java 11.

Esto es trabajo para mí:

...
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
...

public class JsonUtils {

    public static Map parseJSON(String json) throws ScriptException {
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("javascript");

        String script = "Java.asJSONCompatible(" + json + ")";

        Object result = engine.eval(script);

        return (Map) result;
    }
}

Uso de la muestra

JSON

{
    "data":[
        {"id":1,"username":"bruce"},
        {"id":2,"username":"clark"},
        {"id":3,"username":"diana"}
    ]
}

Código:

...
import jdk.nashorn.internal.runtime.JSONListAdapter;
...

public static List<String> getUsernamesFromJson(Map json) {
    List<String> result = new LinkedList<>();

    JSONListAdapter data = (JSONListAdapter) json.get("data");

    for(Object obj : data) {
        Map map = (Map) obj;
        result.add((String) map.get("username"));
    }

    return result;
}

0

Prueba este código:

  public static Map<String, Object> convertJsonIntoMap(String jsonFile) {
        Map<String, Object> map = new HashMap<>();
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
            mapper.readValue(jsonFile, new TypeReference<Map<String, Object>>() {
            });
            map = mapper.readValue(jsonFile, new TypeReference<Map<String, String>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }

-1

JSON to Map siempre será un tipo de datos de cadena / objeto. Tengo GSON lib de google.

funciona muy bien y JDK 1.5 es el requisito mínimo.


1
¿Cómo usaste GSON?
NinjaCoder
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.