Convertir JSON en carte


191

Quelle est la meilleure façon de convertir un code JSON comme suit:

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

dans une Java Map dans laquelle une des clés sont (champ1, champ2) et les valeurs de ces champs sont (valeur1, valeur2).

Des idées? Dois-je utiliser Json-lib pour cela? Ou mieux si j'écris mon propre analyseur?


J'ai écrit du code pour cela sans utiliser de bibliothèque. stackoverflow.com/questions/21720759/jsonobject-to-map/…
Vikas Gupta

Réponses:


336

J'espère que vous plaisantiez sur l'écriture de votre propre analyseur. :-)

Pour un mappage aussi simple, la plupart des outils de http://json.org (section java) fonctionneraient. Pour l'un d'entre eux (Jackson https://github.com/FasterXML/jackson-databind/#5-minute-tutorial-streaming-parser-generator ), vous feriez:

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

(où JSON_SOURCE est un fichier, un flux d'entrée, un lecteur ou une chaîne de contenu json)


37
De plus, si vous voulez une Map typée (exploitant les génériques Java), vous pouvez faire: Map <String, MyPojo> typedMap = mapper.readValue (jsonStream, new TypeReference <Map <String, MyPojo >> () {});
obe6

5
Si vous travaillez avec un projet Maven, vous aurez besoin de <dependency> <groupId> com.fasterxml.jackson.core </groupId> <artifactId> jackson-databind </artifactId> <version> 2.4.4 </version> </ dependency >
LoBo

2
Et on dirait que Jackson a déménagé depuis 09 alors: Jackson data-bind
jacob.mccrumb

@ obe6 Je suppose que l'OP ne plaisante pas. Pouvez-vous trouver un seul "JSON" n'importe où dans votre extrait de code autre que ce nom de variable arbitraire? Je me bats aussi à cause des noms dans l'API Jackson.
Aetherus

FWTW, alors que @ obe6 de réponse est techniquement correcte, vous pouvez utiliser le formulaire plus court aussi: Map<String,Object> result = mapper.readValue(source, Map.class).
StaxMan

36

Utilisation de la bibliothèque GSON:

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

Utilisez le code suivant:

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

7
java à son meilleur: TypeToken<Map<String, Map>>:-)
froderik

2
Avec le nouveau TypeToken <Map <String, Object >>, cela fonctionnera également lorsqu'il y a des tableaux à l'intérieur.
9ilsdx 9rvj 0lo

33

J'aime la bibliothèque google gson .
Lorsque vous ne connaissez pas la structure de json. Vous pouvez utiliser

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

et ensuite vous pouvez travailler avec json. par exemple, comment obtenir "value1" de votre gson:

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

19
Cela peut lancer NullPointerExceptions de 5 manières différentes si vous obtenez des données inattendues.
dfraser

Vous pouvez utiliser .path () maintenant et il ne lancera pas de NPE
C2H50H

18

Utilisez la bibliothèque JSON, par exemple 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

Mon message pourrait être utile pour d'autres, alors imaginez que vous avez une carte avec un objet spécifique dans les valeurs, quelque chose comme ça:

{  
   "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
      }
   }
}

Pour analyser ce fichier JSON avec la bibliothèque GSON, c'est simple: si votre projet est mavenisé

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

Ensuite, utilisez cet extrait:

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

Le POJO correspondant devrait être quelque chose comme ça:

public class ShoppingList {

    int id;

    String label;

    boolean current;

    int nb_reference;

    //Setters & Getters !!!!!
}

J'espère que ça aide !


5

De cette façon, cela fonctionne comme une carte ...

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
Oui, mais vous devez encapsuler chaque «objectif» dans try / catch à cause d'exceptions JSON.
Maciej Swic

1
vous pouvez écrire une classe JsonMap implements Map<String,Objectpour envelopper JSONObject. alors vous obtenez la véritable Mapinterface.
Jeffrey Blattman

Veuillez ajouter les bibliothèques utilisées.
mvermand

5

Je le fais de cette façon. C'est simple.

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

J'ai essayé cette approche mais cela ne fonctionne pas ... pouvez-vous répondre à cela? stackoverflow.com/questions/60329223/…
Siva le

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

Avec le Gson 2.7 de Google (probablement des versions antérieures aussi, mais j'ai testé 2.7) c'est aussi simple que:

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

Ce qui renvoie une Map de type class com.google.gson.internal.LinkedTreeMapet travaille récursivement sur les objets imbriqués.


1

Une autre alternative est json-simple qui peut être trouvée dans Maven Central :

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

L'artefact fait 24 Ko, n'a pas d'autres dépendances d'exécution.


Je nullreviens d'une simple chaîne JSON où l'une des valeurs est un tableau de chaînes.
isapir le

1

Si vous utilisez org.json, JSONObject a une méthode toMap(). Vous pouvez facilement faire:

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

0
import net.sf.json.JSONObject

JSONObject.fromObject(yourJsonString).toMap

0

La bibliothèque Underscore-java peut convertir une chaîne json en carte de hachage. Je suis le mainteneur du projet.

Exemple de code:

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 vous avez besoin de Java pur sans aucune dépendance, vous pouvez utiliser la compilation dans l'API Nashorn de Java 8. Il est obsolète dans Java 11.

Cela fonctionne pour moi:

...
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;
    }
}

Exemple d'utilisation

JSON:

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

Code:

...
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

Essayez ce code:

  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 sera toujours un type de données chaîne / objet. j'ai eu la lib GSON de google.

fonctionne très bien et JDK 1.5 est l'exigence minimale.


1
Comment avez-vous utilisé GSON?
NinjaCoder
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.