การแยกอาร์เรย์ JSON ลงใน java.util.List ด้วย Gson


119

ฉันมีJsonObjectชื่อที่"mapping"มีเนื้อหาดังต่อไปนี้:

{
    "client": "127.0.0.1",
    "servers": [
        "8.8.8.8",
        "8.8.4.4",
        "156.154.70.1",
        "156.154.71.1"
    ]
}

ฉันรู้ว่าฉันสามารถรับอาร์เรย์"servers"ด้วย:

mapping.get("servers").getAsJsonArray()

และตอนนี้ฉันต้องการแยกวิเคราะห์JsonArrayเป็นjava.util.List...

วิธีที่ง่ายที่สุดในการทำคืออะไร?



2
@ruakh มีความแตกต่างมากมายระหว่างคำถามนั้นกับคำถามนี้ อันนี้เกี่ยวข้องกับGson.
Abel Callejo

@AbelMelquiadesCallejo ดูคำตอบฉันหวังว่ามันจะแก้ปัญหาของคุณได้
Prateek

@ruakh ใช่ฉันเห็นด้วยกับคุณและฉันรู้ว่าการดำเนินการJsonArray Iterableเพียงแต่ว่าฉันกำลังหาวิธีใหม่ ๆ นอกเหนือจากการเพิ่มห้องสมุดใหม่
Abel Callejo

คำตอบ:


273

วิธีที่ง่ายที่สุดในการทำเช่นนั้นคือการใช้ฟังก์ชันแยกวิเคราะห์เริ่มต้นของ Gson fromJson()แน่นอนวิธีที่ง่ายที่สุดที่จะทำคือการใช้ฟังก์ชั่นการแยกเริ่มต้นของ

มีการดำเนินงานของฟังก์ชั่นนี้เหมาะสำหรับเมื่อคุณจำเป็นต้องเข้าสู่ deserialize ใด ๆParameterizedType(เช่นใด ๆList) fromJson(JsonElement json, Type typeOfT)ซึ่งเป็น

ในกรณีของคุณคุณต้องได้รับTypea List<String>จากนั้นแยกวิเคราะห์อาร์เรย์ JSON ในTypeลักษณะนี้:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

JsonElement yourJson = mapping.get("servers");
Type listType = new TypeToken<List<String>>() {}.getType();

List<String> yourList = new Gson().fromJson(yourJson, listType);

ในกรณีของคุณyourJsonคือ a JsonElementแต่อาจเป็น a String, any Readerหรือ aJsonReader .

คุณอาจต้องการที่จะดูที่เอกสาร Gson API


8
Typeได้ในแพ็คเกจอะไร?
Abel Callejo

10
Typeเป็นอินเทอร์เฟซในตัว Java ที่อยู่ในแพ็คเกจjava.lang.reflect
MikO

ฉันต้องใช้getString()แทนget()ไม่งั้น.fromJson()ก็บ่น
lenooh

@MikO ฉันมีคำถามคล้ายกับ Gson ที่นี่ ฉันอยากจะดูว่าคุณสามารถช่วยฉันได้ไหม ฉันมีวิธีแก้ปัญหา แต่ปัญหาคือมันดูยุ่งมากเพียงแค่แยกวิเคราะห์ JSON ลงในแผนที่
ห์น

18

com.google.gson.JsonArrayด้านล่างนี้คือการใช้รหัส ฉันได้พิมพ์จำนวนองค์ประกอบในรายการรวมทั้งองค์ประกอบในรายการ

import java.util.ArrayList;

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


public class Test {

    static String str = "{ "+ 
            "\"client\":\"127.0.0.1\"," + 
            "\"servers\":[" + 
            "    \"8.8.8.8\"," + 
            "    \"8.8.4.4\"," + 
            "    \"156.154.70.1\"," + 
            "    \"156.154.71.1\" " + 
            "    ]" + 
            "}";

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {

            JsonParser jsonParser = new JsonParser();
            JsonObject jo = (JsonObject)jsonParser.parse(str);
            JsonArray jsonArr = jo.getAsJsonArray("servers");
            //jsonArr.
            Gson googleJson = new Gson();
            ArrayList jsonObjList = googleJson.fromJson(jsonArr, ArrayList.class);
            System.out.println("List size is : "+jsonObjList.size());
                    System.out.println("List Elements are  : "+jsonObjList.toString());


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

เอาท์พุท

List size is : 4

List Elements are  : [8.8.8.8, 8.8.4.4, 156.154.70.1, 156.154.71.1]

8

ฉันอ่านวิธีแก้ปัญหาจากเว็บไซต์อย่างเป็นทางการของ Gson ที่นี่

และรหัสนี้สำหรับคุณ:

    String json = "{"client":"127.0.0.1","servers":["8.8.8.8","8.8.4.4","156.154.70.1","156.154.71.1"]}";

    JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
    JsonArray jsonArray = jsonObject.getAsJsonArray("servers");

    String[] arrName = new Gson().fromJson(jsonArray, String[].class);

    List<String> lstName = new ArrayList<>();
    lstName = Arrays.asList(arrName);

    for (String str : lstName) {
        System.out.println(str);
    }    

ผลลัพธ์แสดงบนจอภาพ:

8.8.8.8
8.8.4.4
156.154.70.1
156.154.71.1

คำตอบเดียวกับข้างต้น - ยังคงใช้วิธีการคงที่new Gson().fromJson()
Abel Callejo

ปัญหาของฉันเป็นอย่างอื่น แต่ตัวอย่างของคุณช่วยแก้ปัญหาของฉันได้ ฉันเก็บรายการสตริงไว้ แต่ฉันต้องการดึงข้อมูลสตริง จากนั้นตัวอย่างข้อมูลของคุณจำฉันได้ว่าฉันสามารถใส่คลาส String []. เพื่อดึงข้อมูลได้ ขอบคุณ
badarshahzad

2

ฉันสามารถรับการแมปรายการเพื่อใช้งานได้โดยใช้@SerializedNameกับทุกช่องเท่านั้น .. ไม่Typeจำเป็นต้องใช้ตรรกะรอบ ๆ

การรันโค้ด - ในขั้นตอนที่ # 4 ด้านล่าง - ผ่านดีบักเกอร์ฉันสังเกตได้ว่าList<ContentImage> mGalleryImagesวัตถุที่เติมข้อมูล JSON

นี่คือตัวอย่าง:

1. JSON

   {
    "name": "Some House",
    "gallery": [
      {
        "description": "Nice 300sqft. den.jpg",
        "photo_url": "image/den.jpg"
      },
      {
        "description": "Floor Plan",
        "photo_url": "image/floor_plan.jpg"
      }
    ]
  }

2. คลาส Java พร้อมรายการ

public class FocusArea {

    @SerializedName("name")
    private String mName;

    @SerializedName("gallery")
    private List<ContentImage> mGalleryImages;
}

3. คลาส Java สำหรับรายการรายการ

public class ContentImage {

    @SerializedName("description")
    private String mDescription;

    @SerializedName("photo_url")
    private String mPhotoUrl;

    // getters/setters ..
}

4. โค้ด Java ที่ประมวลผล JSON

    for (String key : focusAreaKeys) {

        JsonElement sectionElement = sectionsJsonObject.get(key);
        FocusArea focusArea = gson.fromJson(sectionElement, FocusArea.class);
    }

0

เมื่อคุณเริ่มต้นด้วยmapping.get("servers").getAsJsonArray()หากคุณสามารถเข้าถึงGuava Streamsได้คุณสามารถทำซับเดียวด้านล่าง:

List<String> servers = Streams.stream(jsonArray.iterator())
                              .map(je -> je.getAsString())
                              .collect(Collectors.toList());

หมายเหตุStreamSupportจะไม่สามารถทำงานกับJsonElementประเภทได้ดังนั้นจึงไม่เพียงพอ

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