Phân tích cú pháp mảng JSON thành java.util.List với Gson


119

Tôi có một cái JsonObjecttên "mapping"với nội dung sau:

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

Tôi biết tôi có thể lấy mảng "servers"với:

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

Và bây giờ tôi muốn phân tích cú pháp đó JsonArraythành java.util.List...

cách dễ nhất để làm điều này là gì?



2
@ruakh có nhiều điểm khác biệt giữa câu hỏi đó và câu hỏi này. Điều này giải quyết với Gson.
Abel Callejo

@AbelMelquiadesCallejo hãy xem câu trả lời, tôi hy vọng nó sẽ giải quyết được vấn đề của bạn.
Prateek,

@ruakh vâng, tôi đồng ý với bạn và tôi biết JsonArraydụng cụ Iterable. Chỉ là tôi cũng đang tìm những cách mới ngoài việc thêm một thư viện mới.
Abel Callejo,

Câu trả lời:


272

Chắc chắn cách dễ nhất để làm điều đó là sử dụng chức năng phân tích cú pháp mặc định của Gson fromJson().

Có một cách triển khai của chức năng này phù hợp khi bạn cần giải mã hóa thành bất kỳ ParameterizedType(ví dụ: bất kỳ List) nào fromJson(JsonElement json, Type typeOfT).

Trong trường hợp của bạn, bạn chỉ cần lấy Typea List<String>và sau đó phân tích cú pháp mảng JSON thành đó Type, như sau:

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

Trong trường hợp của bạn yourJsonlà a JsonElement, nhưng cũng có thể là a String, any Readerhoặc a JsonReader.

Bạn có thể muốn xem tài liệu API Gson .


7
Typecó thể được tìm thấy trong những gì gói?
Abel Callejo

10
Typelà một giao diện tích hợp sẵn của Java nằm trong góijava.lang.reflect
MikO

Tôi đã phải sử dụng getString()thay vì get()hoặc người khác .fromJson()đã được phàn nàn.
lenooh

@MikO Tôi có một câu hỏi tương tự với Gson ở đây . Tôi muốn xem nếu bạn có thể giúp tôi. Tôi có một giải pháp nhưng vấn đề là nó trông rất lộn xộn chỉ để phân tích cú pháp JSON thành một Bản đồ.
john

18

Dưới đây là mã đang sử dụng com.google.gson.JsonArray. Tôi đã in số phần tử trong danh sách cũng như các phần tử trong Danh sách

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

}

ĐẦU RA

List size is : 4

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

8

Tôi đọc giải pháp từ trang web chính thức của Gson tại đây

Và mã này dành cho bạn:

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

Kết quả hiển thị trên màn hình:

8.8.8.8
8.8.4.4
156.154.70.1
156.154.71.1

cùng câu trả lời như trên - vẫn sử dụng phương pháp tĩnhnew Gson().fromJson()
Abel Callejo

vấn đề của tôi là khác nhưng đoạn mã của bạn giải quyết vấn đề của tôi. Tôi đã lưu trữ danh sách chuỗi nhưng tôi muốn tìm nạp các chuỗi. Sau đó, đoạn mã của bạn gợi nhớ cho tôi về lớp của chúng Tôi có thể đặt lớp String []. Để tìm nạp dữ liệu. Cảm ơn bạn
badarshahzad

2

Tôi đã có thể làm cho ánh xạ danh sách hoạt động chỉ với việc sử dụng @SerializedNamecho tất cả các trường .. không cần logic xung quanh Type.

Chạy mã - trong bước # 4 bên dưới - thông qua trình gỡ lỗi, tôi có thể quan sát thấy List<ContentImage> mGalleryImagesđối tượng được điền bằng dữ liệu JSON

Đây là một ví dụ:

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. Lớp Java với Danh sách

public class FocusArea {

    @SerializedName("name")
    private String mName;

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

3. Lớp Java cho các mục Danh sách

public class ContentImage {

    @SerializedName("description")
    private String mDescription;

    @SerializedName("photo_url")
    private String mPhotoUrl;

    // getters/setters ..
}

4. Mã Java xử lý JSON

    for (String key : focusAreaKeys) {

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

0

Nếu bạn đã bắt đầu mapping.get("servers").getAsJsonArray(), nếu bạn có quyền truy cập vào Guava Streams , bạn có thể thực hiện theo một bước dưới đây:

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

Ghi chú StreamSupportsẽ không thể hoạt động trên JsonElementloại, vì vậy nó không đủ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.