retrofit
retrofit copied to clipboard
Bug : Problem with response body, not parsing body if response is 202
I know that Retrofit does not allow the Call without any return types, developer should have to add some object in return type like
@GET
Call<Response<JsonObject>> checkStatus(@Url String url);
Above is client application request checking status of data. In this request, client app gets two types of different responses 200 success
with body & 202 accepted
without body. Client app have to call this request with an interval of 5 or n seconds whenever in response client app gets 202 accepted
response. If other than 202
it gets different status code then client app stops this calling this request.
So in this case, client app accept return type of Response<JsonObject>
In 202
accepted response there is no body. So it is gives error :
Retrofit2 error java.io.EOFException: End of input at line 1 column 1
I changed this Response<JsonObject>
to Response<Object>
& Response<String>
, but still gives same above error.
So I solved this issue by changing return type of request from Response<JsonObject>
to Response<Void>
as it is suggested here
@GET
Call<Response<Void>> checkStatus(@Url String url);
Now above request is working fine for 202
accepted response. But not working when client app gets 200
success response & in that response server sends body in it. In Response object app can not gets body because of return type Void
.
In above request of return type I use Response
object like Call<Response>
. I use this object because client app needs to check HTTP
status code like 200
, 202
etc. I changed from Call<Response>
to Call<ResponseBody>
but it does not return status code. Only Call<Response>
object returns HTTP
status code.
In same request, how can I handle null/empty body if I get 202
accepted status code & body data if I get 200
success status code?
I know that, Retrofit does not allow Call without type like Call<Response<Void>>
or Call<Response<JsonObject>>
and is not able to map empty body, but what if one of developer have above use case? How can it will be solve? I don't know about any standardization of accepting body only if 200
& not in 202
, is there any standard way to do this?
I through modify converter solved this problem. For example,i modify the JacksonResponseBodyConverter
so when server not return response body the converter return a default value:
@Override
public T convert(ResponseBody value) throws IOException {
try {
if (value.contentLength() == 0) {
return (T) new Object();
}
return adapter.readValue(value.charStream());
} finally {
value.close();
}
}
I test it and works well,but I don't know other people need it or not?
I've write test scenario in CallTest.java, but it passed. This commit link is here.
I would like you help me to reconstruct your case, so that one can help you to solve this issue.
@Jiachen-Zhang Thanks for your help. I gone through your code. In your test case you set body empty string.
server.enqueue(new MockResponse().setResponseCode(202).setBody(""));
Instead of empty body just try null
means Void
. You will get error. From server my application get null
body & response is 202
and it is successfully works with other client application like iOS, Java SpringBoot.
Please do send null
in body
hey @mangeshsambare did you figure this out? just bumped into something similar and i've tried a few different approaches:
- using
Call<Void>
, - using
Call<ResponseBody>
, - using a custom Converter.Factory, like the NullOnEmptyConverterFactory you'll find here.
unfortunately no luck yet, i'd appreciate some help.