Phân tích cú pháp JSON bằng Gson cho Java


154

Tôi muốn phân tích dữ liệu từ JSON là loại String. Tôi đang sử dụng Google Gson .

Tôi có:

jsonLine = "
{
 "data": {
  "translations": [
   {
    "translatedText": "Hello world"
   }
  ]
 }
}
";

và lớp học của tôi là:

public class JsonParsing{

   public void parse(String jsonLine) {

      // there I would like to get String "Hello world"

   }

}

Câu trả lời:


241

Đây là mã đơn giản để làm điều đó, tôi tránh tất cả các kiểm tra nhưng đây là ý chính.

 public String parse(String jsonLine) {
    JsonElement jelement = new JsonParser().parse(jsonLine);
    JsonObject  jobject = jelement.getAsJsonObject();
    jobject = jobject.getAsJsonObject("data");
    JsonArray jarray = jobject.getAsJsonArray("translations");
    jobject = jarray.get(0).getAsJsonObject();
    String result = jobject.get("translatedText").getAsString();
    return result;
}

Để làm cho việc sử dụng chung chung hơn - bạn sẽ thấy rằng javadocs của Gson khá rõ ràng và hữu ích.


1
JsonObject mở rộng JsonEuity, vì vậy nó là cả hai.
MByD

dòng ném đầu tiên không thể khởi tạo kiểu JsonParser trên phiên bản gson-2.2.4.jar
Đối số bất hợp pháp

3
Chuỗi kết quả = jobject.get ("translText"). ToString (); Kết quả này sẽ bao gồm các trích dẫn kép. Chuỗi kết quả = jobject.get ("translText"). GetAsString (); không bao gồm các trích dẫn.
dùng1165560

Al Tôi là người duy nhất nghĩ rằng Gson làm quá mức mọi thứ 98% thời gian? Một JSONObject đơn giản sẽ làm được, nhưng tất cả chúng ta đều ghét thử / bắt nhiều như vậy?
thủ thuật

Tôi cần sử dụng lớp trình phân tích cú pháp, tuy nhiên, tôi đang nhận được MalformedJsonException, vì vậy tôi phải có khả năng thực hiện SetLeinient với JsonParser. Làm sao?
Mason Wang

111

Trong ứng dụng gson đầu tiên của tôi, tôi đã tránh sử dụng các lớp bổ sung để bắt các giá trị chủ yếu vì tôi sử dụng json cho các vấn đề cấu hình

mặc dù thiếu thông tin (thậm chí trang gson), đó là những gì tôi tìm thấy và sử dụng:

bắt đầu từ

Map jsonJavaRootObject = new Gson().fromJson("{/*whatever your mega complex object*/}", Map.class)

Mỗi lần gson nhìn thấy {}, nó sẽ tạo ra một Bản đồ (thực ra là một gMap StringMap)

Mỗi lần gson nhìn thấy một '', nó tạo ra một Chuỗi

Mỗi lần gson nhìn thấy một con số, nó sẽ tạo ra một Double

Mỗi lần gson nhìn thấy [], nó tạo ra một ArrayList

Bạn có thể sử dụng sự thật này (kết hợp) để lợi thế của bạn

Cuối cùng, đây là mã tạo nên sự vật

        Map<String, Object> javaRootMapObject = new Gson().fromJson(jsonLine, Map.class);

    System.out.println(
        (
            (Map)
            (
                (List)
                (
                    (Map)
                    (
                        javaRootMapObject.get("data")
                    )
                 ).get("translations")
            ).get(0)
        ).get("translatedText")
    );

20

Điều đơn giản nhất thường là tạo phân cấp đối tượng phù hợp, như vậy:

public class Wrapper {
   public Data data;
}
static class Data {
   public Translation[] translations;
}
static class Translation {
   public String translatedText;
}

và sau đó liên kết bằng GSON, phân cấp đối tượng qua các trường. Thêm getters và setters là vô nghĩa đối với các thùng chứa dữ liệu cơ bản.

Vì vậy, một cái gì đó như:

Wrapper value = GSON.fromJSON(jsonString, Wrapper.class);
String text = value.data.translations[0].translatedText;

2
Sau đó, cấu trúc đối tượng của bạn KHÔNG khớp với JSON.
Staxman


8

Bạn có thể sử dụng một lớp riêng để biểu diễn đối tượng JSON và sử dụng @SerializedNamecác chú thích để chỉ định tên trường cần lấy cho từng thành viên dữ liệu:

public class Response {

   @SerializedName("data")
   private Data data;

   private static class Data {
      @SerializedName("translations")
      public Translation[] translations;
   }

   private static class Translation {
      @SerializedName("translatedText")
      public String translatedText;
   }

   public String getTranslatedText() {
      return data.translations[0].translatedText;
   }
}

Sau đó, bạn có thể thực hiện phân tích cú pháp trong phương thức parse () của mình bằng một Gsonđối tượng:

Gson gson = new Gson();
Response response = gson.fromJson(jsonLine, Response.class);

System.out.println("Translated text: " + response.getTranslatedText());

Với cách tiếp cận này, bạn có thể sử dụng lại Responselớp để thêm bất kỳ trường bổ sung nào khác để chọn các thành viên dữ liệu khác mà bạn có thể muốn trích xuất từ ​​JSON - trong trường hợp bạn muốn thay đổi để có kết quả, giả sử, nhiều bản dịch trong một cuộc gọi, hoặc để có được một chuỗi bổ sung cho ngôn ngữ nguồn được phát hiện.


7

Một cách sẽ được tạo ra một JsonObject và lặp qua các tham số. Ví dụ

JsonObject jobj = new Gson().fromJson(jsonString, JsonObject.class);

Sau đó, bạn có thể trích xuất các giá trị bean như:

String fieldValue = jobj.get(fieldName).getAsString();
boolean fieldValue = jobj.get(fieldName).getAsBoolean();
int fieldValue = jobj.get(fieldName).getAsInt();

Hi vọng điêu nay co ich.


5

Sử dụng Gson để giải quyết
tôi sẽ tạo một lớp cho tham số riêng lẻ trong Chuỗi json. Ngoài ra, bạn có thể tạo một lớp chính gọi là "Dữ liệu" và sau đó tạo các lớp bên trong tương tự. Tôi đã tạo các lớp riêng biệt cho rõ ràng.

Các lớp học như sau.

  • Dữ liệu
  • Bản dịch
  • Đã dịch

Trong lớp JsonParsing, phương thức "parse" mà chúng ta gọi gson.fromJson(jsonLine, Data.class)sẽ chuyển đổi Chuỗi trong các đối tượng java bằng Reflection.

Khi chúng ta có quyền truy cập vào đối tượng "Dữ liệu", chúng ta có thể truy cập từng tham số riêng lẻ.

Không có cơ hội kiểm tra mã này khi tôi rời khỏi máy dev của mình. Nhưng điều này sẽ giúp.

Một số ví dụ và bài viết tốt.
http://albertattard.blogspot.com/2009/06/prreal-example-of-gson.html
http://sites.google.com.vn/site/gson/gson-user-guide

public class JsonParsing{

       public void parse(String jsonLine) {

           Gson gson = new GsonBuilder().create();
           Data data = gson.fromJson(jsonLine, Data.class);

           Translations translations = data.getTranslation();
           TranslatedText[] arrayTranslatedText = translations.getArrayTranslatedText(); //this returns an array, based on json string

           for(TranslatedText translatedText:arrayTranslatedText )
           {
                  System.out.println(translatedText.getArrayTranslatedText());
           }
       }

    }


    public class Data{
           private  Translations translations;
          public Translations getTranslation()
          {
             return translations;
          }

          public void setTranslation(Translations translations)
           {
                  this.translations = translations;
           }
    }

    public class Translations
    {
        private  TranslatedText[] translatedText;
         public TranslatedText[] getArrayTranslatedText()
         {
             return translatedText;
         }

           public void setTranslatedText(TranslatedText[] translatedText)
           {
                  this.translatedText= translatedText;
           }
    }

    public class TranslatedText
    {
        private String translatedText;
        public String getTranslatedText()
        {
           return translatedText;
        }

        public void setTranslatedText(String translatedText)
        {
           this.translatedText = translatedText;
        }
    }

Bạn không cần một số setters trên các lớp người trợ giúp? Không có gì có thể thiết lập private String translatedTextmà không vi phạm kiểm soát truy cập, vì vậy không có cách nào fromJSONcó thể thiết lập nó trong các JVM chưa chọn tham gia phản chiếu chà đạp lên tất cả các kiểm soát truy cập.
Mike Samuel

@Mike Samuel hoàn toàn quên đi Setters
kensen john

3
    JsonParser parser = new JsonParser();
    JsonObject jo = (JsonObject) parser.parse(data);
    JsonElement je = jo.get("some_array");

    //Parsing back the string as Array
    JsonArray ja = (JsonArray) parser.parse(o.get("some_array").getAsString());
    for (JsonElement jo : ja) {
    JsonObject j = (JsonObject) jo;
        // Your Code, Access json elements as j.get("some_element")
    }

Một ví dụ đơn giản để phân tích cú pháp JSON như thế này

{"some_array": "[\" some_element \ ": 1, \" some_more_element \ ": 2]", "some_other_element": 3}


2

Trước tiên hãy tạo Getter và Setter bằng cách sử dụng trang phân tích bên dưới

http://www.jsonschema2pojo.org/

Bây giờ sử dụng Gson

GettetSetterClass object=new Gson().fromjson(jsonLine,GettetSetterClass.class);

Bây giờ sử dụng đối tượng để nhận các giá trị như dữ liệu, dịch thuật


2

Bạn có thể sử dụng truy vấn JsonPath để trích xuất giá trị. Và với JsonSurfer được hỗ trợ bởi Gson, vấn đề của bạn có thể được giải quyết chỉ bằng hai dòng mã!

    JsonSurfer jsonSurfer = JsonSurfer.gson();
    String result = jsonSurfer.collectOne(jsonLine, String.class, "$.data.translations[0].translatedText");

1

Mã một dòng:

System.out.println(new Gson().fromJson(jsonLine,JsonObject.class).getAsJsonObject().get("data").getAsJsonObject().get("translations").getAsJsonArray().get(0).getAsJsonObject().get("translatedText").getAsString());
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.