1. ホーム
  2. android

[解決済み] RetrofitでDynamic JSONを扱うには?

2023-05-01 11:29:51

質問

retrofit efficient networking libraryを使用していますが、単一の接頭辞を含むDynamic JSONを扱うことができません。 responseMessage という接頭辞があり、それが object ランダムに、同じ接頭辞( responseMessage ) が String に変わる場合があります (動的に)。

responseMessageのJson形式のObject。

{
   "applicationType":"1",
   "responseMessage":{
      "surname":"Jhon",
      "forename":" taylor",
      "dob":"17081990",
      "refNo":"3394909238490F",
      "result":"Received"
   }

}

responseMessage Json形式は動的に文字列に変更されます。

 {
       "applicationType":"4",
       "responseMessage":"Success"          
 }

私の問題は、retrofit には組み込みの JSON をパースするので、リクエストごとにひとつの POJO を割り当てなければなりません。 JSON レスポンスで構築されています。の両方でプレフィックスが文字列からオブジェクトにランダムに変更されます。 成功(...) failure(...) メソッドがあります!

void doTrackRef(Map<String, String> paramsref2) {
    RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint("http://192.168.100.44/RestDemo").build();



    TrackerRefRequest userref = restAdapter.create(TrackerRefRequest.class);
    userref.login(paramsref2,
            new Callback<TrackerRefResponse>() {
                @Override
                public void success(
                        TrackerRefResponse trackdetailresponse,
                        Response response) {

                    Toast.makeText(TrackerActivity.this, "Success",
                    Toast.LENGTH_SHORT).show();

                }

                @Override
                public void failure(RetrofitError retrofitError) {


                    Toast.makeText(TrackerActivity.this, "No internet",
                        Toast.LENGTH_SHORT).show();
                }


            });
}

ポジョ

public class TrackerRefResponse {


private String applicationType;

    private String responseMessage;          //String type

//private ResponseMessage responseMessage;  //Object of type ResponseMessage

//Setters and Getters


}

上記のコードでは、POJO TrackerRefResponse.java のプレフィックス responseMessage が string または responseMessage 型のオブジェクトに設定されているので、同じ名前の ref 変数で POJO を作成できます (java 基本 :) ) ので、動的にも同じソリューションを探しているところです。 JSON をRetrofitで使えるようにしたいのです。 通常のhttpクライアントでは非同期タスクで簡単にできることですが、REST-APIではベストプラクティスではありません。 JSON をパースすることです!パフォーマンスを見ると ベンチマーク いつもVolleyかRetrofitがベストチョイスなんですが、ハンドルダイナミックに失敗してます。 JSON !

私が知っている可能な解決策

  1. httpクライアントのパースで古いasycタスクを使用する :(

  2. RESTapiバックエンドの開発者を説得してみる。

  3. カスタムRetrofitクライアントを作成する :)

どのように解決するのですか?

遅ればせながら、コンバータを使用するとよいでしょう。

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint("https://graph.facebook.com")
    .setConverter(new DynamicJsonConverter()) // set your static class as converter here
    .build();

api = restAdapter.create(FacebookApi.class);

そして、retrofitのConverterを実装した静的なクラスを使用します。

static class DynamicJsonConverter implements Converter {

    @Override public Object fromBody(TypedInput typedInput, Type type) throws ConversionException {
        try {
            InputStream in = typedInput.in(); // convert the typedInput to String
            String string = fromStream(in);
            in.close(); // we are responsible to close the InputStream after use

            if (String.class.equals(type)) {
                return string;
            } else {
                return new Gson().fromJson(string, type); // convert to the supplied type, typically Object, JsonObject or Map<String, Object>
            }
        } catch (Exception e) { // a lot may happen here, whatever happens
            throw new ConversionException(e); // wrap it into ConversionException so retrofit can process it
        }
    }

    @Override public TypedOutput toBody(Object object) { // not required
        return null;
    }

    private static String fromStream(InputStream in) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder out = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            out.append(line);
            out.append("\r\n");
        }
        return out.toString();
    }
}

このサンプルコンバータは、JsonレスポンスをString, Object, JsonObject, Map< String, Object >のいずれかで返すように書きました。もちろん、すべての返り値がすべてのJsonに対して機能するわけではありませんし、改善の余地もあります。しかし、これは、コンバータを使用して、ほとんどすべてのレスポンスを動的なJsonに変換する方法を示しています。