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.