แปลง JSON เป็น Map


191

วิธีที่ดีที่สุดในการแปลงรหัส JSON คือ:

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

ใน Java Map ซึ่งหนึ่งในคีย์คือ (field1, field2) และค่าสำหรับฟิลด์เหล่านั้นคือ (value1, value2)

ความคิดใด ๆ ฉันควรใช้ Json-lib เพื่อสิ่งนั้นหรือไม่? หรือดีกว่าถ้าฉันเขียน parser ของตัวเอง?


ฉันได้เขียนโค้ดสำหรับสิ่งนี้โดยไม่ใช้ห้องสมุดใด ๆ stackoverflow.com/questions/21720759/jsonobject-to-map/…
Vikas Gupta

คำตอบ:


336

ฉันหวังว่าคุณล้อเล่นเกี่ยวกับการเขียน parser ของคุณเอง :-)

สำหรับการทำแผนที่อย่างง่ายเครื่องมือส่วนใหญ่จากhttp://json.org (ส่วน java) จะทำงานได้ สำหรับหนึ่งในนั้น (แจ็คสันhttps://github.com/FasterXML/jackson-databind/#5-minute-tutorial-streaming-parser-generator ) คุณต้องการ:

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

(โดยที่ JSON_SOURCE คือไฟล์, อินพุตสตรีม, ตัวอ่านหรือสตริงเนื้อหา json)


37
ยิ่งไปกว่านั้นถ้าคุณต้องการพิมพ์แผนที่ (ใช้ประโยชน์จากจาวาทั่วไป) คุณสามารถทำได้: แผนที่ <String, MyPojo> typedMap = mapper.readValue (jsonStream, TypeReference ใหม่ <Map <String, MyPojo >> () {});
obe6

5
หากคุณทำงานกับโครงการ Maven คุณจะต้อง <dependency> <groupId> com.fasterxml.jackson.core </groupId> <artifactId> jackson-databind </artifactId> <version> 2.4.4 </version> </ การพึ่งพา >
LoBo

2
และดูเหมือนว่าแจ็คสันได้ย้ายมาตั้งแต่ 09 ดังนั้น: Jackson data-bind
jacob.mccrumb

@ obe6 ฉันเดาว่า OP ไม่ได้ล้อเล่น คุณสามารถหา "JSON" หนึ่งเดียวที่ใดก็ได้ในข้อมูลโค้ดของคุณนอกเหนือจากชื่อตัวแปรนั้นหรือไม่ ฉันดิ้นรนเหมือนกันเพราะชื่อใน Jackson API
Aetherus

FWTW ในขณะที่คำตอบของ @ obe6 นั้นถูกต้องทางเทคนิคคุณสามารถใช้แบบฟอร์มที่สั้นลงได้เช่นกัน: Map<String,Object> result = mapper.readValue(source, Map.class).
StaxMan

36

ใช้ไลบรารี GSON:

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

ใช้รหัสต่อไปนี้:

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

7
java ที่ดีที่สุด: TypeToken<Map<String, Map>>:-)
froderik

2
ด้วย TypeToken <Map <String, Object >> ใหม่จะทำงานได้เมื่อมีอาร์เรย์อยู่ภายใน
9ilsdx 9rvj 0lo

33

ฉันชอบห้องสมุดgoogle gson
เมื่อคุณไม่รู้จักโครงสร้างของ json คุณสามารถใช้ได้

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

และจากนั้นคุณสามารถทำงานกับ json เช่นวิธีรับ "value1" จาก gson ของคุณ:

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

19
วิธีนี้จะทำให้ NullPointerExceptions 5 วิธีแตกต่างกันหากคุณได้รับข้อมูลที่ไม่คาดคิด
dfraser

คุณสามารถใช้. path () ได้แล้วมันจะไม่โยน NPE
C2H50H

18

ใช้ JSON lib Eg 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

โพสต์ของฉันอาจเป็นประโยชน์สำหรับผู้อื่นดังนั้นโปรดจินตนาการว่าคุณมีแผนที่ที่มีวัตถุเฉพาะเป็นค่าเช่นนี้:

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

ในการแยกวิเคราะห์ไฟล์ JSON นี้ด้วยไลบรารี GSON มันเป็นเรื่องง่าย: ถ้าโครงการของคุณถูกลบล้าง

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

จากนั้นใช้ตัวอย่างนี้:

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

POJO ที่เกี่ยวข้องควรเป็นดังนี้:

public class ShoppingList {

    int id;

    String label;

    boolean current;

    int nb_reference;

    //Setters & Getters !!!!!
}

หวังว่ามันจะช่วย!


5

วิธีนี้ทำงานเหมือนแผนที่ ...

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
ใช่ แต่คุณต้องล้อมทุก´get´ ไว้ในลอง / จับเนื่องจากข้อยกเว้น JSON
Maciej Swic

1
คุณสามารถเขียนคลาสJsonMap implements Map<String,Objectเพื่อตัด JSONObject จากนั้นคุณจะได้รับMapอินเตอร์เฟซที่แท้จริง
Jeffrey Blattman

กรุณาเพิ่มห้องสมุดที่ใช้แล้ว
mvermand

5

ฉันทำอย่างนี้ มันง่าย

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

ฉันลองใช้วิธีนี้ แต่มันไม่ทำงาน ... คุณสามารถตอบคำถามนี้ได้หรือไม่ stackoverflow.com/questions/60329223/…
ศิวะ

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

ด้วย Gson 2.7 ของ Google (อาจเป็นรุ่นก่อนหน้านี้ด้วย แต่ฉันทดสอบ 2.7) มันง่ายเหมือน:

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

ซึ่งส่งคืนแผนที่ประเภทclass com.google.gson.internal.LinkedTreeMapและทำงานซ้ำบนวัตถุที่ซ้อนกัน


1

อีกทางเลือกหนึ่งคือjson-simpleซึ่งสามารถพบได้ในMaven Central :

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

สิ่งประดิษฐ์คือ 24kbytes ไม่มีการพึ่งพารันไทม์อื่น ๆ


ฉันnullกลับมาจากสตริง JSON แบบง่ายโดยที่หนึ่งในค่านั้นคืออาร์เรย์ของสตริง
isapir

1

หากคุณกำลังใช้ org.json, JSONObject toMap()มีวิธีการ คุณสามารถทำได้อย่างง่ายดาย:

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


0

ขีด-จาวาไลบรารีสามารถแปลงสตริง json เป็นแผนที่แฮช ฉันเป็นผู้ดูแลโครงการ

ตัวอย่างรหัส:

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

หากคุณต้องการจาวาบริสุทธิ์โดยไม่ต้องพึ่งพาใด ๆ คุณสามารถใช้บิลด์ใน Nashorn API จาก Java 8 ซึ่งเลิกใช้แล้วใน Java 11

นี่ใช้งานได้สำหรับฉัน:

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

ตัวอย่างการใช้งาน

JSON:

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

รหัส:

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

ลองรหัสนี้:

  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 จะเป็นประเภทข้อมูลสตริง / วัตถุเสมอ ฉันได้รับ GSON lib จาก google

ทำงานได้ดีมากและ JDK 1.5 เป็นข้อกำหนดขั้นต่ำ


1
คุณใช้ GSON อย่างไร
NinjaCoder
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.