【问题标题】:parse a JSON feed using GSON and get an array instead of multi params使用 GSON 解析 JSON 提要并获取数组而不是多参数
【发布时间】:2013-02-20 13:35:31
【问题描述】:

我正在尝试在 Android 应用程序上解析 ELGG resfull 网络服务 (http://elgg.pro.tn/services/api/rest/json/?method=system.api.list)。

我正在使用 GSON 库将 JSON 提要转换为 JAVA 对象,我为转换(映射)创建了所有需要的类

问题在于 JSON 格式(我无法更改):

{
   "status":0,
   "result":{
      "auth.gettoken":{
         "description":"This API call lets a user obtain a user authentication token which can be used for authenticating future API calls. Pass it as the parameter auth_token",
         "function":"auth_gettoken",
         "parameters":{
            "username":{
               "type":"string",
               "required":true
            },
            "password":{
               "type":"string",
               "required":true
            }
         },
         "call_method":"POST",
         "require_api_auth":false,
         "require_user_auth":false
      },
      "blog.delete_post":{
         "description":"Read a blog post",
         "function":"blog_delete_post",
         "parameters":{
            "guid":{
               "type":"string",
               "required":true
            },
            "username":{
               "type":"string",
               "required":true
            }
         },
         "call_method":"POST",
         "require_api_auth":true,
         "require_user_auth":false
      }
   }
}

这种格式的“结果”包含许多不具有相同名称的子项(即使它们具有我称为“apiMethod”的相同结构),GSON 尝试将其解析为分离的对象,但我想要的是他将所有“结果”子项解析为“apiMethod”对象。

【问题讨论】:

    标签: java android json parsing gson


    【解决方案1】:

    如果您不想在Result 对象中定义所有可能的字段,您可以使用Map 而不是数组来执行此操作。

    class MyResponse {
    
       int status; 
       public Map<String, APIMethod> result;    
    }
    
    class APIMethod {
    
        String description;
        String function;
        // etc
    }
    

    否则,您需要定义一个 Result 对象来使用,而不是使用所有可能的“方法”类型作为字段的 Map,并使用 @SerializedName 注释,因为 Java 名称不合法:

    class Result {
        @SerializedName("auth.gettoken")
        APIMethod authGetToken;
        @SerializedName("blog.delete_post")
        APIMethod blogDeletePost;
        // etc
    }
    

    如果您真的想要一个List,选项 C 正在创建您自己的自定义反序列化器,该反序列化器将传递已解析的 JSON,并创建一个包含 List 而不是 Map 的对象或 POJO。

    class MyResponse {
        public int status;
        public List<APIMethod> methods;
    
        public MyResponse(int status, List<APIMethod> methods) {
            this.status = status;
            this.methods = methods;
        }
    }
    
    
    class MyDeserializer implements JsonDeserializer<MyResponse> {
    
        public MyResponse deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException
        {
            Gson g = new Gson();
            List<APIMethod> list = new ArrayList<APIMethod>();
            JsonObject jo = je.getAsJsonObject();
            Set<Entry<String, JsonElement>> entrySet = jo.getAsJsonObject("result").entrySet();
            for (Entry<String, JsonElement> e : entrySet) {
                APIMethod m = g.fromJson(e.getValue(), APIMethod.class);
                list.add(m);
            }
    
            return new MyResponse(jo.getAsJsonPrimitive("status").getAsInt(), list);
        }
    }
    

    (未经测试,但应该可以)

    要使用它,您需要注册它:

    Gson gson = new GsonBuilder()
                    .registerTypeAdapter(MyResponse.class, new MyDeserializer())
                    .create();
    

    【讨论】:

    • 这很有帮助。谢谢
    猜你喜欢
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    相关资源
    最近更新 更多