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

标签 java android json parsing gson

我正在尝试在 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”对象。

最佳答案

您可以使用 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
}

如果你真的想要一个 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();

关于java - 使用 GSON 解析 JSON 提要并获取数组而不是多参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14981196/

相关文章:

android - 在三星设备上使用蓝牙低功耗时什么也没发现

android - 0x00000000 处的致命信号 7 (SIGBUS)(代码=2)

java - 当我们可以在 Restful 服务中使用 jsonObject 时,为什么还需要 POJO

java - Android 中的 Watson 视觉识别

Android + ESP32 通过蓝牙 (BLE) 发送数据

javascript - ajax 将多部分表单数据上传为 json 对象

php - 如何将 JSON 数据从 Android 发送到 php url?

JSON 序列化与 XPath 3.1 fn :serialize

java - 登录tomcat不起作用

java - ArrayList 到字符串数组