2017-05-05 96 views
1

我有一個JSON結構,我想使用retrofit 2(@Expose)進行解析。下面我提到了JSON。需要幫助來解析它使用動態註釋。如何使用註解解析動態json在android中使用retrofit 2

{ 
    "status": 1, 
    "message": "success", 
    "data" : [ 
    { 
     "type": 1, 
     "heading": "", 
     "description": "", 
     "created_on": 141123213, 
     "author_id": 123, 
     "author_name": "some name", 
     "author_pic": "some_pic", 
     "read_time": "3.1 min", 
     "post_pic_url": "", 
     "post_web_url": "", 
     "isLiked": false, 
     "isSaved": false, 
     "totalLikes": 12 
    }, 
    { 
     "type": 2, 
     "author_id": 123, 
     "author_name": "some name", 
     "author_pic": "some pic", 
     "author_about": "", 
     "tags":[ 
     "travel", "weekends" 
     ], 
     "isFollowing": false 
    }, 
    { 
    "type": 3, 
    "poll_name": "Some name", 
    "poll_options": [ 
     "opt1", "opt2", "opt3" 
    ], 
    "author_id": 123, 
    "author_name": "some name", 
    "author_pic": "some pic", 
    "isLiked": true, 
    "isFollowing": false 
    }, 
    { 
    "type": 4, 
    "ad_url": "url", 
    "ad_pic": "pic" 
    }, 
    { 
    "type": 5, 
    "tags": [ 
     "tag1", "tag2", "tag3" 
    ] 
    } 
    ] 
} 

我已經更新了所有5種類型的JSON結構。

+0

動態註釋是指每次json結構會發生變化? – Lingeshwaran

+1

在問這裏之前你有什麼嘗試嗎? –

+0

當然,我試圖創建一個與JSON中提到的所有項目的模型,這是可行的,但不是我想要的最佳解決方案。尋找一些有效的方法 – ketan268

回答

1

1使用改造轉換 例如GSON轉換

2添加com.squareup.retrofit2:變換器GSON的gradle中文件 3添加轉換器工廠在改造對象

改造改型=新Retrofit.Builder( ) .baseUrl(Ws_Url) .addConverterFactory(GsonConverterFactory.create()) .client(clientBuilder.build()) .build();

4您的回覆 使用下面的鏈接生成模型類 http://www.jsonschema2pojo.org/

+0

該服務無法處理多態JSON。 –

+0

是的,這不會有幫助,因爲模型類中的項目根據Jensen結構的JSON結構應該是不同的。如果我在模型類上創建所有json項目,那麼它會拋出異常,因爲它找不到其他json數組項目的KEY。 – ketan268

0

改造不做序列化和反序列化創建模型類,但GSON一樣。 您可能想要使用Google Gson extras軟件包中的RuntimeTypeAdapterFactory。 它不在工件存儲庫中發佈,您可以簡單地將代碼複製到您的項目中。 如果類型適配器有點複雜(因爲它們使用JSON流),您可能會發現JsonDeserializer<T>更易於使用,並且可能會維護(它們可以與消耗更多內存的JSON樹一起工作,但是它仍然是唯一的途徑)。

定義類似的映射:

// There might be no the common root, and target lists might be parameterized with Object, but it's up to you 
abstract class Element { 

    final int type = Integer.valueOf(0); 

    // Since the number of types is really finite, we can define all known types in one place 
    private Element() { 
    } 

    static final class Type1Element 
      extends Element { 

     // the rest of properties go here 

     // Gson does not need constructors, neither we do (at least public ones) 
     private Type1Element() { 
     } 

    } 

    static final class Type2Element 
      extends Element { 

     // the rest of properties go here 

     private Type2Element() { 
     } 

    } 

} 
final class Response<T> { 

    final int status = Integer.valueOf(0); 
    final String message = null; 
    final T data = null; 

} 

現在解串器本身:

final class ElementJsonDeserializer 
     implements JsonDeserializer<Element> { 

    private static final JsonDeserializer<Element> elementJsonDeserializer = new ElementJsonDeserializer(); 

    private ElementJsonDeserializer() { 
    } 

    // The deserializer is essentially a singleton, but we hide away this fact making sure that only 1 instance exists 
    static JsonDeserializer<Element> getElementJsonDeserializer() { 
     return elementJsonDeserializer; 
    } 

    @Override 
    public Element deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) 
      throws JsonParseException { 
     final int typeCode = jsonElement.getAsJsonObject().getAsJsonPrimitive("type").getAsInt(); 
     // Simple dispatching here 
     // RuntimeTypeAdapterFactory basically does the same 
     switch (typeCode) { 
     case 1: 
      return context.deserialize(jsonElement, Type1Element.class); 
     case 2: 
      return context.deserialize(jsonElement, Type2Element.class); 
     default: 
      throw new JsonParseException("Unrecognized type: " + typeCode); 
     } 
    } 

} 

現在得到它一起工作(response.json是您的JSON文件資源):

private static final Type type = new TypeToken<Response<List<Element>>>() { 
}.getType(); 

private static final Gson gson = new GsonBuilder() 
     .registerTypeAdapter(Element.class, getElementJsonDeserializer()) 
     .create(); 

public static void main(final String... args) 
     throws IOException { 
    try (final JsonReader jsonReader = getPackageResourceJsonReader(Q43802350.class, "response.json")) { 
     final Response<List<Element>> response = gson.fromJson(jsonReader, type); 
     response.data 
       .stream() 
       .map(Element::getClass) 
       .map(Class::getSimpleName) 
       .forEach(System.out::println); 
    } 
} 

輸出:

Type1Element
Type2Element

當然,不要忘了在Retrofit建設者註冊gson實例與GsonConverterFactory.create(gson)

+0

好的。我會試試看 – ketan268