はじめに
今日はRetrofit+OkHttpでファイルダウンロードするAPI呼び出しについて書いていきたいと思います。
検索すると古いバージョンの話やAndroidに特化した内容の記事が多くヒットしたのですが、今回紹介するのはWebサイトで同期的にAPIを呼び出す前提のやり方です。
バージョン
- retrofit:2.9.0
- okhttp:3.14.9
実装方法
Retrofitのインスタンス生成
レスポンスをバイト列で受け取りたいので今回はコンバーターを設定しません。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://localhost:8080")
// コンバーターを指定しない
//.addConverterFactory(JacksonConverterFactory.create())
.build();
インターフェイスの実装
サービスから戻り値を変換せずにokhttp3.ResponseBody
で受け取るように宣言します。また@Streaming
をつけておかないとダウンロードしたファイルが一気にメモリに展開されてOutOfMemoryErrorが起きる可能性があるので注意してください。
public interface DownloadService {
@Streaming
@GET("/download")
Call<ResponseBody> download();
}
呼び出し方
あとはAPIを呼び出して取得したレスポンスに対してresponse.body().byteStream()
するとダウンロードしたファイルがInputStreamで取得できるのでファイルに保存するなり好きにしてください。
// API呼び出し
DownloadService service = retrofit.create(DownloadService.class);
Response<ResponseBody> response = service.download().execute();
InputStream is = new BufferedInputStream(response.body().byteStream());
OutputStream os = new BufferedOutputStream(
new FileOutputStream(new File("/tmp/test.gif")));
try (is; os) {
int read = 0;
byte[] bytes = new byte[1024];
while ((read = is.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
}
おしまい
以上、最近仕事で実装しているRetrofitについての3日間連続投稿でした。