応答として返される前に、JSON応答を編集するためにインターセプター((OkHttp 3.2&Retrofit 2)を実装しようとしています。データを要求するサーバーが異なるデータを返すのは、成功またはエラーによって異なり、オブジェクトのマッピングが困難になります。
インターセプターをNetworkInterceptorとしてRetrofitに追加することでそれを実行しようとしましたが、返された文字列にはフォーマットがありませんでした。
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
try {
final String responseString = new String(response.body().bytes() );
LOGD("OkHttp-NET-Interceptor", "Response: " + responseString);
String newResponseString = editResponse( responseString );
LOGD("OkHttp-NET-Interceptor", "Response edited: " + newResponseString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), newResponseString))
.build();
}catch (Exception ex){
return response;
}
}
responseStringには、理解できる形式のない文字列が含まれていました。
通常のインターセプターに変更した後、文字列の形式はJSONObjectに変換できました。
responsesの違いは誰か教えてください。
なぜこの行new String(response.body()。bytes());は異なるコンテンツを返すのですか?
違いは名前にあります。 NetworkInterceptor
はネットワークレベルでフックし、再試行ロジックや応答の実際のコンテンツに依存しないものを配置するのに理想的な場所です。
(あなたの場合のように)応答の内容に依存する場合は、ApplicationInterceptor
を使用する方が便利です。これは、以下のような他の可動部分によって処理された後の応答を提供するためです。 JSONデシリアライザ。そうでない場合は、NetworkInterceptor
内にJSONの逆シリアル化を実装する必要があります。これは、Retrofitによって行われたことを考えるとあまり意味がありません。
説明
スクエアには、Wikiにこの便利な図があり、インターセプターの各タイプがどこにあるかを示しています
したがって、ApplicationInterceptor
で読み取り可能な文字列を受け取るのは、Squareが2つのインターセプタータイプの目的を切り離そうとしているためです。 NetworkInterceptor
でアプリケーションに依存する決定を行う必要があると彼らは考えておらず、応答文字列にアクセスする簡単な方法を提供していません。理解することは可能ですが、私が言ったように、彼らはあなたが応答の内容に依存する決定をすることを望んでいません-むしろ、彼らはあなたがベースやネットワーク状態、またはヘッダーなどに基づいて決定することを望んでいます。
ApplicationInterceptor
は、応答の内容に応じて決定を下す場所です。そのため、応答の内容にアクセスするための簡単な方法が提供されるため、情報に基づいた再試行の決定を行うことができます。彼らのウィキ、 リライト応答 (私はあなたがやろうとしていることだと私は信じています)。