Home » Android » android – How can I handle empty response body with Retrofit 2?

android – How can I handle empty response body with Retrofit 2?

Posted by: admin March 11, 2020 Leave a comment


Recently I started using Retrofit 2 and I faced an issue with parsing empty response body. I have a server which responds only with http code without any content inside the response body.

How can I handle only meta information about server response (headers, status code etc)?

How to&Answers:


As Jake Wharton points out,

Call<Void> getMyData(/* your args here */);

is the best way to go versus my original response —

You can just return a ResponseBody, which will bypass parsing the response.

Call<ResponseBody> getMyData(/* your args here */);

Then in your call,

Call<ResponseBody> dataCall = myApi.getMyData();
dataCall.enqueue(new Callback<ResponseBody>() {
    public void onResponse(Response<ResponseBody> response) {
        // use response.code, response.headers, etc.

    public void onFailure(Throwable t) {
        // handle failure


If you use RxJava, then it’s better to use Completable in this case

Represents a deferred computation without any value but only indication for completion or exception. The class follows a similar event pattern as Reactive-Streams: onSubscribe (onError|onComplete)?


in the accepted answer:

Observable<Response<Void>> getMyData(/* your args here */);

If the endpoint returns failure response code, it will still be in the onNext and you will have to check the response code yourself.

However, if you use Completable.

Completable getMyData(/* your args here */);

you will have only onComplete and onError.
if the response code is success it will fire the onComplete else it will fire onError.


If you are using rxjava, use something like :

Observable<Response<Void>> getMyData(/* your args here */);


Here is how I used it with Rx2 and Retrofit2, with PUT REST request:
My request had a json body but just http response code with empty body.

The Api client:

public class ApiClient {
public static final String TAG = ApiClient.class.getSimpleName();

private DevicesEndpoint apiEndpointInterface;

public DevicesEndpoint getApiService() {

    Gson gson = new GsonBuilder()

    OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();

    OkHttpClient okHttpClient = okHttpClientBuilder.build();

    apiEndpointInterface = new Retrofit.Builder()

    return apiEndpointInterface;


The interface:

public interface DevicesEndpoint {
 @Headers("Content-Type: application/json")
 Observable<ResponseBody> sendDeviceDetails(@Body Device device);

Then to use it:

    private void sendDeviceId(Device device){

    ApiClient client = new ApiClient();
    DevicesEndpoint apiService = client.getApiService();
    Observable<ResponseBody> call = apiService.sendDeviceDetails(device);

    Log.i(TAG, "sendDeviceId: about to send device ID");
    call.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<ResponseBody>() {
        public void onSubscribe(Disposable disposable) {

        public void onNext(ResponseBody body) {
            Log.i(TAG, "onNext");

        public void onError(Throwable t) {
            Log.e(TAG, "onError: ", t);


        public void onComplete() {
            Log.i(TAG, "onCompleted: sent device ID done");