使用GSON解析JSON提要并获取数组而不是多个参数

时间:2013-02-20 13:35:31

标签: java android json parsing gson

我正在尝试在Android应用程序上解析ELGG resfull webservice(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'对象。

1 个答案:

答案 0 :(得分:4)

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

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
}

选项C如果确实希望List正在创建您自己的自定义反序列化器,该反序列化器传递已解析的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();