2015-02-04 27 views
20

Tôi đã hỏi câu hỏi này trong một câu hỏi khác hôm nay nhưng tôi e rằng sẽ không nhận được bất kỳ giải pháp nào vì nó bị phrased ra sao.Gson - Tên trường giống nhau, các loại khác nhau

Tôi có một đầu vào json có các dữ liệu sau:

Json

Như bạn có thể thấy, mục option_value là một mảng trong một đối tượng và một chuỗi đơn giản trong một đối tượng khác.

Làm cách nào để Gson có thể xử lý đúng cách? Lớp của tôi được mô tả dưới dạng đối tượng Danh sách, vì vậy nó hoạt động cho một vài mục đầu tiên trong đó option_value là một mảng, nhưng khi nó trở thành một chuỗi , sự cố ứng dụng và tôi nhận được một trường hợp phân tích cú pháp json json.

Có cách giải quyết nào cho vấn đề này không?

CẬP NHẬT

Thêm phần liên quan của lớp học của tôi theo yêu cầu:

public class Options 
    { 
     String product_option_id; 
     String option_id; 
     String name; 
     String type; 
     String required; 
     List<OptionValue> option_value; 

     // get set stuff here 

     public class OptionValue 
     { 
      String product_option_value_id; 
      String option_value_id; 
      String name; 
      String image; 
      String price; 
      String price_prefix; 

      // get set stuff here 
     } 
    } 
+0

Xin chào Asim, bạn có thể hiển thị Trình phân tích cú pháp Json của bạn không? – Kansen

+0

Đã thêm phần có liên quan. Tôi đang sử dụng Gson để phân tích cú pháp được thực hiện bởi thư viện đó bằng cách sử dụng hàm Gson.fromJson (chuỗi, lớp). – Asim

+0

Bạn không thể đạt được điều này bằng cách sử dụng 'GSON.fromJson (String json, Class classOfT)', bạn sẽ phải xác định adapter của bạn ... cho phép nói 'StrangeJsonAdapter' bằng cách mở rộng lớp' com.google.gson.TypeAdapter' .. sau đó sử dụng phương thức 'StrangeJsonAdapter.fromJson (String json)' để giải mã json của bạn. –

Trả lời

16

Tôi có một giải pháp cho bạn :) Với mục đích này, chúng ta nên sử dụng deserializer tùy chỉnh. Làm lại lớp học của bạn như thế này:

public class Options{ 

    @SerializedName ("product_option_id"); 
    String mProductOptionId; 

    @SerializedName ("option_id"); 
    String mOptionId; 

    @SerializedName ("name"); 
    String mName; 

    @SerializedName ("type"); 
    String mType; 

    @SerializedName ("required"); 
    String mRequired; 

    //don't assign any serialized name, this field will be parsed manually 
    List<OptionValue> mOptionValue; 

    //setter 
    public void setOptionValues(List<OptionValue> optionValues){ 
     mOptionValue = optionValues; 
    } 

    // get set stuff here 
    public class OptionValue 
    { 
     String product_option_value_id; 
     String option_value_id; 
     String name; 
     String image; 
     String price; 
     String price_prefix; 

     // get set stuff here 
    } 

public static class OptionsDeserilizer implements JsonDeserializer<Options> { 

    @Override 
    public Offer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
     Options options = new Gson().fromJson(json, Options.class); 
     JsonObject jsonObject = json.getAsJsonObject(); 

     if (jsonObject.has("option_value")) { 
      JsonElement elem = jsonObject.get("option_value"); 
      if (elem != null && !elem.isJsonNull()) { 
       String valuesString = elem.getAsString(); 
       if (!TextUtils.isEmpty(valuesString)){ 
        List<OptionValue> values = new Gson().fromJson(valuesString, new TypeToken<ArrayList<OptionValue>>() {}.getType()); 
        options.setOptionValues(values); 
       } 
      } 
     } 
     return options ; 
    } 
} 
} 

Trước khi chúng ta có thể để cho gson parse json, chúng ta nên đăng ký deserializer tùy chỉnh của chúng tôi:

Gson gson = new GsonBuilder()    
      .registerTypeAdapter(Options.class, new Options.OptionsDeserilizer())    
      .create(); 

Và bây giờ - chỉ cần gọi:

Options options = gson.fromJson(json, Options.class); 
+1

Tôi có một StackOverflowError do cuộc gọi deserialization đệ quy trên chính nó tại 'Tùy chọn tùy chọn = new Gson(). TừJson (json, Options.class);' và hai mới 'Gson' trường hợp được tạo ra trong deserialization của một đối tượng duy nhất. Coi chưng. – EpicPandaForce

2

Trong tôi trường hợp, trường có cùng tên là "dữ liệu": {} hoặc "dữ liệu": [array_with_real_data]. Vì vậy, mã từ câu trả lời được chấp nhận cần phải được sửa đổi một chút, như sau:

@Override 
public MyClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 
     throws JsonParseException { 
    MyClass bean = new Gson().fromJson(json, MyClass.class); 
    JsonObject jsonObject = json.getAsJsonObject(); 

    if (jsonObject.has("data")) { 
     JsonArray array = jsonObject.getAsJsonArray("data"); 
     if (array != null && !array.isJsonNull()) { 
      List<Data> data = new Gson().fromJson(array, new TypeToken<ArrayList<Data>>() {}.getType()); 
      bean.realData = data; 
     } 
    } 
    return bean ; 
} 

hy vọng sẽ hữu ích.

Các vấn đề liên quan