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?

David Santamaria
la source
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)

StaxMan
la source
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);
David L
la source
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();
Bugs_
la source
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));

}
jd
la source
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 !

Jad B.
la source
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>
Fabio Araujo
la source
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);
    }
}
Pavan
la source
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 );
nouveauMaziar
la source
3

La bibliothèque JsonTools est très complète. Il peut être trouvé sur Github .

Bruno Ranschaert
la source
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.

isapir
la source
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.

pcjuzer
la source
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();
Omri Levi
la source
0
import net.sf.json.JSONObject

JSONObject.fromObject(yourJsonString).toMap
Li Rao
la source
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}
    }
}
Valentyn Kolesnikov
la source
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;
}
somtomes
la source
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;
    }
Braj Thakur
la source
-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.


la source
1
Comment avez-vous utilisé GSON?
NinjaCoder