Andrew Emad
Andrew Emad

Reputation: 277

retrofit body return null

I have post a request and test it on postman , the response return correctly on postman and android logcat , but on retrofit it returns null in the body

here is the model of the response

public class DriverResponse implements Serializable{
@SerializedName("errors")
@Expose
public Errors errors;
@SerializedName("driversapi")
@Expose
public Driversapi driversapi;
}


public class Errors implements Serializable {

@SerializedName("driversapi")
@Expose
public List<String> driversapi = null;
}

public class Driversapi implements Serializable{
public String driverid ;
public String status ;
public String authtoken ;
}

and here is the code of getting data

public void acceptOrder(String auth, AcceptOrderModel acceptOrderModel) {
    ApiInterface service = ApiClient.getClient().create(ApiInterface.class);
    Call<DriverResponse> connection = service.acceptOrder(auth, acceptOrderModel);
    if (connection != null) {
        connection.enqueue(new Callback<DriverResponse>() {
            @Override
            public void onResponse(Call<DriverResponse> call, Response<DriverResponse> response) {
                String reponseStr = response.toString().replaceAll("\\\\", "");
                Log.e("new String", reponseStr);
                apiResponse.onSuccess(response.body());
            }

            @Override
            public void onFailure(Call<DriverResponse> call, Throwable t) {

                Log.e("QR ", " " + t.getLocalizedMessage());
                apiResponse.onFailed(t.getLocalizedMessage());
            }
        });
    }
}


@Headers({"Content-Type: application/json"})
@POST("/api/drivers/driveracceptorder")
Call<DriverResponse> acceptOrder(@Header("Authorization") String Authorization, @Body AcceptOrderModel acceptOrderModel);

when I send the request , the response getting null response and errorbody content getting this

[size=99 text={\r\n "errors": {\r\n "driversapi": [\r\n "order alredy assig…]

here is the expected json that should return and already return in logcat and postman

{
"errors": {
  "driversapi": [
    "driver not found"
   ]
  }
}

Edit

here is my LogCat

 POST http://site.example.com/api/drivers/driveracceptorder http/1.1
03-09 10:57:17.533 8128-17940/com.trend.driver D/OkHttp: Content-Type: application/json
03-09 10:57:17.533 8128-17940/com.trend.driver D/OkHttp: Content-Length: 47
03-09 10:57:17.533 8128-17940/com.trend.driver D/OkHttp: Authorization: Ber z3rlF3cUYICZUm49HeCkpOU8TEjITCqq5tplXDZU4pxvRlzTScUo-0wZr52trM9kWinOnqzaJBwgMB9pp0tk4GTx7BGDoX-u5H9IfQWHlJ_iYpWOIkTiZOb4JuovPPPTfta4MJlRJO6IjasBKpNTvT7KRqp4gHrw3xs9JWa9RTCuY83JhaBf2weyQ8RwsT_SVTg
03-09 10:57:17.535 8128-17940/com.trend.driver D/OkHttp: {"accept":"1","driverid":"2112","orderid":"46"}
03-09 10:57:17.535 8128-17940/com.xxxx.driver D/OkHttp: --> END POST (47-byte body)
03-09 10:57:17.535 8128-8128/com.trend.driver I/Choreographer: Skipped 115 frames!  The application may be doing too much work on its main thread.
03-09 10:57:18.290 8128-17940/com.trend.driver D/OkHttp: <-- 404 Not Found http://site.example.com/api/drivers/driveracceptorder (754ms)
03-09 10:57:18.291 8128-17940/com.trend.driver D/OkHttp: Cache-Control: private
03-09 10:57:18.291 8128-17940/com.trend.driver D/OkHttp: Content-Length: 99
03-09 10:57:18.291 8128-17940/com.trend.driver D/OkHttp: Content-Type: application/json
03-09 10:57:18.291 8128-17940/com.trend.driver D/OkHttp: Server: Microsoft-IIS/8.5
03-09 10:57:18.291 8128-17940/com.trend.driver D/OkHttp: Set-Cookie: Nop.customer=9df71aba-df96-4aa4-a8f5-daab40d91d5e; expires=Sat, 09-Mar-2019     08:57:18 GMT; path=/; HttpOnly
03-09 10:57:18.291 8128-17940/com.trend.driver D/OkHttp: Date: Fri, 09 Mar 2018 08:57:18 GMT
03-09 10:57:18.294 8128-17940/com.trend.driver D/OkHttp: {
03-09 10:57:18.295 8128-17940/com.trend.driver D/OkHttp:   "errors": {
03-09 10:57:18.295 8128-17940/com.trend.driver D/OkHttp:     "driversapi": [
03-09 10:57:18.295 8128-17940/com.trend.driver D/OkHttp:       "order alredy assigned to other driver"
03-09 10:57:18.295 8128-17940/com.trend.driver D/OkHttp:     ]
03-09 10:57:18.295 8128-17940/com.trend.driver D/OkHttp:   }
03-09 10:57:18.295 8128-17940/com.trend.driver D/OkHttp: }
03-09 10:57:18.295 8128-17940/com.trend.driver D/OkHttp: <-- END HTTP (99-byte body)

Upvotes: 3

Views: 1972

Answers (2)

Navneet Krishna
Navneet Krishna

Reputation: 5017

you should be returning DriverResponse instead of ResponseTest, see below code

 public void acceptOrder(String auth, AcceptOrderModel acceptOrderModel) {
    ApiInterface service = ApiClient.getClient().create(ApiInterface.class);
    Call<DriverResponse> connection = service.acceptOrder(auth, acceptOrderModel);
    if (connection != null) {
        connection.enqueue(new Callback<DriverResponse>() {
            @Override
            public void onResponse(Call<DriverResponse> call, Response<DriverResponse> response) {
                List<String>=response.getErrors().getDriversapi();
                apiResponse.onSuccess(response.body());
            }

            @Override
            public void onFailure(Call<DriverResponse> call, Throwable t) {

                Log.e("QR ", " " + t.getLocalizedMessage());
                apiResponse.onFailed(t.getLocalizedMessage());
            }
        });
    }
}


@Headers({"Content-Type: application/json"})
@POST("/api/drivers/driveracceptorder")
Call<DriverResponse> acceptOrder(@Header("Authorization") String Authorization, @Body AcceptOrderModel acceptOrderModel);

Update your model class with getters as follows

     public class DriverResponse {

    @SerializedName("errors")
@Expose
private Errors errors;

public Errors getErrors() {
return errors;
}

public void setErrors(Errors errors) {
this.errors = errors;
}

    }

and

    public class Errors {

@SerializedName("driversapi")
@Expose
private List<String> driversapi = null;

public List<String> getDriversapi() {
return driversapi;
}

public void setDriversapi(List<String> driversapi) {
this.driversapi = driversapi;
}

}

Now inside onResponse you can get an array of strings as

List<String>=response.getErrors().getDriversapi();

Upvotes: 0

Akinola Olayinka
Akinola Olayinka

Reputation: 861

In the OnResponse callback, you should check if the response is successful or not. If the response is not successful, the response body will be null but the errorBody will have a content. Here is an example:

Call<ArrayList<Town>> callGetTowns = apiCalls.getTownsInState(stateId);
callGetTowns.enqueue(new Callback<ArrayList<Town>>() {

    @Override
    public void onResponse(Call<ArrayList<Town>> call, Response<ArrayList<Town>> response) {
    if (response.isSuccessful()){
        //response is successful so response.body() won't be null
        ArrayList<Town> towns = response.body();

    }else{
        //response is not successful so response.body is null but response.errorBody is not null
        String message = "Server Error!";
        try {
            String errorBody = response.errorBody().string();

            //parse the errorBody string to json and retrieve whichever attribute you want
            JsonObject jsonObject = gson.fromJson(errorBody, JsonObject.class);
            if (jsonObject!=null && jsonObject.has("message") && !jsonObject.get("message").isJsonNull()) {
                message =  jsonObject.get("message").getAsString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
       }
   }

   @Override
   public void onFailure(Call<ArrayList<Town>> call, Throwable t) {
        //request timedout
   }});

Upvotes: 1

Related Questions