如何使用注释在改进2中解析android中的动态json

时间:2017-05-05 10:16:05

标签: java android json gson retrofit2

我有一个JSON结构,我想用改造2(@Expose)解析。下面我提到了JSON。需要帮助来使用动态注释来解析它。

{
  "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结构。

2 个答案:

答案 0 :(得分:1)

1使用Retrofit转换   示例GSON转换

2在gradle文件中添加com.squareup.retrofit2:converter-gson 3在Retrofit对象中添加转换器工厂

Retrofit retrofit = new Retrofit.Builder()             .baseUrl(Ws_Url)             .addConverterFactory(GsonConverterFactory.create())             .client(clientBuilder.build())             .build();

4为您的回复创建Model类   使用以下链接生成模型类   http://www.jsonschema2pojo.org/

答案 1 :(得分:0)

Retrofit不进行序列化和反序列化,但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

当然,不要忘记在gson构建器中使用GsonConverterFactory.create(gson)注册Retrofit个实例。