0
私は監視目的でOkHttpを使って物事を取得するときに、Webサーバレスポンスボディの実際のサイズを記録できるようにします。全体をバッファリングせずにOkHttpレスポンスボディサイズを記録する
レスポンスボディの実際のサイズを取得する方法はありますか(メモ - サーバーが要求したコンテンツ長ではありません)、応答全体をメモリにバッファリングする必要はありませんか?
私は監視目的でOkHttpを使って物事を取得するときに、Webサーバレスポンスボディの実際のサイズを記録できるようにします。全体をバッファリングせずにOkHttpレスポンスボディサイズを記録する
レスポンスボディの実際のサイズを取得する方法はありますか(メモ - サーバーが要求したコンテンツ長ではありません)、応答全体をメモリにバッファリングする必要はありませんか?
これは私が望んでいた何のために働くようで...
AtomicLong bytesRead = new AtomicLong();
OkHttpClient client = new OkHttpClient.Builder().addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
response = response.newBuilder()
.body(
new RealResponseBody(
response.body().contentType().toString(),
response.body().contentLength(),
Okio.buffer(
new LengthTrackingSource(
response.body().source(),
(newBytesRead) -> {
bytesRead.addAndGet(newBytesRead);
}
)
)
)
)
.build();
return response;
}
class LengthTrackingSource implements Source {
private Source source;
private Consumer<Long> lengthRecorder;
public LengthTrackingSource(Source source, Consumer<Long> lengthRecorder) {
this.source = source;
this.lengthRecorder = lengthRecorder;
}
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead;
try {
bytesRead = source.read(sink, byteCount);
} catch (IOException e) {
throw e;
}
// Avoid adding the final -1 (which means the source is exhausted)
if (bytesRead > 0) {
lengthRecorder.accept(bytesRead);
}
return bytesRead;
}
@Override
public Timeout timeout() {
return source.timeout();
}
@Override
public void close() throws IOException {
source.close();
}
}
}).build();
try (Response response = client.newCall(new Request.Builder().url("http://example.com/").build()).execute()) {
System.out.println(bytesRead.get());
String body = response.body().string();
System.out.println(body.length());
System.out.println(bytesRead.get());
}
私はまだそれについて聞いてみたい簡単な方法があります場合は!
しかし、サーバーはcontentLengthについて正しいですよね?この文書をチェックしてください:https://square.github.io/okhttp/3.x/okhttp/okhttp3/ResponseBody.html – rafid059
まあ、コンテンツの長さがコンテンツのどこかからストリーミングされているため不確定な長さ(つまり、ResponseBody.contentLengthが-1を返す場合)...しかし、それは必ずしも私のサーバではなく、おそらく誤った長さのヘッダを返すかもしれません(おそらくokhttpはそれをどうにかして禁止します)。 –
ああ、まだ適切には消化していませんが、https://gist.github.com/digitalbuddha/3c5bb15fa12a553c85ecのreadTwiceのように見えます(2番目の読み取りはちょうど長さを数える実際のコンテンツは無視されます)。 –