问题
I'm working on a Android sample app that get film list from http://www.omdbapi.com/.
The REST service is:
http://www.omdbapi.com/?s=star&apikey=d497e644
I'm using Retrofit to write the client.
public interface OmdbApi {
@Streaming
@GET("./")
@Headers({"Cache-control: no-cache"})
Call<Search> search(@Query("s") String search, @Query("apikey") String apiKey);
@Streaming
@GET("./")
@Headers({"Cache-control: no-cache"})
Call<FilmDetail> getFilm(@Query("i") String uid, @Query("apikey") String apiKey);
}
The complete source code is available here.
When I run the application, I obtain the following response (taken from logcat):
OK http://www.omdbapi.com/?s=star&apikey=d497e644 (108ms)
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Cache-Control: public, max-age=86400
Expires: Sat, 26 May 2018 14:28:18 GMT
Last-Modified: Fri, 25 May 2018 05:39:04 GMT
Vary: *, Accept-Encoding
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
CF-Cache-Status: HIT
Server: cloudflare
CF-RAY: 4208b00c817b3db9-MXP
Connection: Keep-Alive
And the following error:
java.net.ProtocolException: unexpected end of stream
at okhttp3.internal.http1.Http1Codec$ChunkedSource.read(Http1Codec.java:455)
at okio.RealBufferedSource.read(RealBufferedSource.java:47)
okio.RealBufferedSource.exhausted(RealBufferedSource.java:57)
okio.InflaterSource.refill(InflaterSource.java:102)
okio.InflaterSource.read(InflaterSource.java:62)
okio.GzipSource.read(GzipSource.java:80)
okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:237)
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
at okhttp3.RealCall.execute(RealCall.java:77)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:91)
com.abubusoft.filmfinder.service.repository.FilmRepository.lambda$findFilm$0$FilmRepository(FilmRepository.java:18)
com.abubusoft.filmfinder.service.repository.FilmRepository$$Lambda$0.run(Unknown Source:20)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
After a bit of investigation, I found that the problem is that the response has Transfer-Encoding: chunked
. How can I resolve this problem?
Thank you.
回答1:
After more investigation:
- I remove the
@Streaming
annotations.. they aren't useful. - Tests that I did was on an emulator on a PC behind a firewall.
OkHttp
had some problem about it many years ago, but now chunked transfer is completely managed.- On the same machine, invoking the same URL in a browser does not present any problems
I finally try on another machine, with a JUnit test and in Android emulator and I had no problem.
At last, I'm sure that code works, so is the environment that I used to develop the app has some problem with transfer-encoding chunked.
Complete source code is available here:
- android app
- junit test
I have to find exactly what is the problem, I'm sure now that it not Retrofit or my client definition or OkHttp.
I hope my experience can help other developers.
Byez
来源:https://stackoverflow.com/questions/50531718/retrofit-client-and-response-with-transfer-encoding-chunked