I saw topics like How to download file in Android using Retrofit library?, they use @Streaming
and RxJava / callbacks.
I have Kotlin, coroutines, Retrof
You can change the return type of exportPdf
to Call
and then check the response code. If it's ok then read the body as a stream. If it's not then try to deserialize ExportResponse.
It will look something like this I guess:
val response = restAdapter.apiRequest().execute()
if (response.isSuccessful) {
response.body()?.byteStream()//do something with stream
} else {
response.errorBody()?.string()//try to deserialize json from string
}
Update
Here is a complete listing of my test:
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.http.GET
import retrofit2.http.Url
import java.io.File
import java.io.InputStream
fun main() {
val queries = buildQueries()
check(queries, "http://127.0.0.1:5000/error")
check(queries, "http://127.0.0.1:5000/pdf")
}
private fun check(queries: Queries, url: String) {
val response = queries.exportPdf(HttpUrl.get(url)).execute()
if (response.isSuccessful) {
response.body()?.byteStream()?.saveToFile("${System.currentTimeMillis()}.pdf")
} else {
println(response.errorBody()?.string())
}
}
private fun InputStream.saveToFile(file: String) = use { input ->
File(file).outputStream().use { output ->
input.copyTo(output)
}
}
private fun buildRetrofit() = Retrofit.Builder()
.baseUrl("http://127.0.0.1:5000/")
.client(OkHttpClient())
.build()
private fun buildQueries() = buildRetrofit().create(Queries::class.java)
interface Queries {
@GET
fun exportPdf(@Url url: HttpUrl): Call
}
and here is simple sever built with Flask:
from flask import Flask, jsonify, send_file
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, World!'
@app.route('/error')
def error():
response = jsonify(error=(dict(body='some error')))
response.status_code = 400
return response
@app.route('/pdf')
def pdf():
return send_file('pdf-test.pdf')
all works fine for me
Update 2
Looks like you have to write this in your Api:
@FormUrlEncoded
@Streaming // You can also comment this line.
@POST("export-pdf/")
fun exportPdf(
@Field("token") token: String
): Call