web-dev-qa-db-ja.com

成功したレスポンスボディをレトロフィットを使用して特定のタイプに変換するにはどうすればよいですか?

非同期モードでは、レトロフィットコール

_public void success(T t, Response rawResponse)
_

tは変換された応答であり、rawResponseは生の応答です。これにより、生の応答と変換された応答の両方にアクセスできます。

同期モードでは、変換された応答[〜#〜]または[〜#〜]生の応答のいずれかを取得できます

変換された応答

_@GET("/users/list")
List<User> userList();
_

生の応答

_@GET("/users/list")
Response userList();
_

Responseオブジェクトには、本体を取得するメソッドがあります

_TypedInput  getBody()
_

そしてretrofitapiには、これをJavaオブジェクトに変換できるコンバータークラスがあります

_Object fromBody(TypedInput body,Type type)
_

しかし、Converterオブジェクトのインスタンスを取得する方法がわかりません

Converterクラスのインスタンスを作成できる場合もありますが、それには、RestAdapterの作成に使用されるGsonオブジェクトの知識が必要であり、アクセスできない場合があります。理想的には、RestAdpaterに直接コンバーターオブジェクトへの参照を取得したいと思います。


次のいずれかが私の質問に答えます:

  1. レトロフィットで使用されるデフォルトのコンバーターへの参照を取得する方法はありますか?
  2. デフォルトのコンバーターがどのように構築されているか知っている人はいますか? (デフォルトのコンストラクターはなく、2つのコンストラクターpublic GsonConverter(Gson gson)とpublicGsonConverter(Gson gson、String charset)があります。
  3. 同期モードで生の応答と変換された応答の両方を取得する他の方法はありますか?
12
nPn

これは、retrofitで見つかったStringConverterを実装するConverterクラスの例です。基本的には、fromBody()をオーバーライドして、必要なものを指定する必要があります。

public class StringConverter implements Converter {

    /*
     * In default cases Retrofit calls on GSON which expects a JSON which gives
     * us the following error, com.google.gson.JsonSyntaxException:
     * Java.lang.IllegalStateException: Expected BEGIN_OBJECT but was
     * BEGIN_ARRAY at line x column x
     */

    @Override
    public Object fromBody(TypedInput typedInput, Type type)
            throws ConversionException {

        String text = null;
        try {
            text = fromStream(typedInput.in());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return text;
    }

    @Override
    public TypedOutput toBody(Object o) {
        return null;
    }

    // Custom method to convert stream from request to string
    public static String fromStream(InputStream in) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder out = new StringBuilder();
        String newLine = System.getProperty("line.separator");
        String line;
        while ((line = reader.readLine()) != null) {
            out.append(line);
            out.append(newLine);
        }
        return out.toString();
    }
}

これをリクエストに適用するには、次のことを行う必要があります。

// initializing Retrofit's rest adapter
RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint(ApiConstants.MAIN_URL).setLogLevel(LogLevel.FULL)
        .setConverter(new StringConverter()).build();
8