3

Android アプリケーションでELGG resfull Web サービス ( 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」オブジェクトとしてのすべての「結果」の子。

4

1 に答える 1

4

Mapオブジェクトで可能なすべてのフィールドを定義したくない場合は、配列ではなくを使用してこれを行うことができResultます。

class MyResponse {

   int status; 
   public Map<String, APIMethod> result;    
}

class APIMethod {

    String description;
    String function;
    // etc
}

それ以外の場合は、可能なすべての「メソッド」タイプをフィールドとして持つResultオブジェクトの代わりに使用するオブジェクトを定義し、正当でない Java 名のためにアノテーションを使用する必要があります。Map@SerializedName

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

本当に必要な場合のオプション CListは、解析された JSON が渡される独自のカスタム デシリアライザーを作成し、または POJOListの代わりに を含むオブジェクトを作成することです。Map

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-02-20T14:45:53.530 に答える