SN069
SN069

Reputation: 21

Why I can not successfully send JSON in a POST request using Retrofit in my android app

I am using Retrofit library in my Android App to send GET and POST calls to the backend API. The POST request is ending up in failure block with the 500 Internal Server Error with no other details.

I have added the following dependencies:

compile 'com.google.code.gson:gson:2.3.1'    
compile 'com.squareup.retrofit:retrofit:1.6.1'
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.5.0'
compile 'com.squareup.okio:okio:1.6.0'

Class representing the JSON Body

public class Feedback {
    private String type;
    private String message;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

Class representing the JSON request response

public class ApiResponse {
    private Boolean status;

    public Boolean getStatus() {
        return status;
    }

    public void setStatus(Boolean status) {
        this.status = status;
    }
}

The Retrofit interface

public interface ISupportApi {
    @Headers({
            "Accept: application/json",
            "Content-type: application/json"
    })
    @POST("/common/feedback")
    void sendFeedback(@Body String feedback, Callback<ApiResponse> callback);
}

The method which is responsible to send the POST request using Retrofit.

public void sendFeedback(Feedback feedback){

    try {
        ISupportApi service = restAdapter.create(ISupportApi.class);

        String json = convertToJSON(feedback);

        service.sendFeedback(json, new Callback<ApiResponse>() {

            @Override
            public void success(ApiResponse apiResponse, Response response){
                boolean status = true;

                try {
                    if (apiResponse != null) {
                        //do Something
                    }

                } catch (Exception ex) {
                    Log.e(TAG, Constants.GENERAL_ERROR_MESSAGE, ex);
                }
            }

            @Override
            public void failure(RetrofitError error) {
                boolean status = false;
                Log.e(TAG, Constants.CALL_FAILED_ERROR_MESSAGE);
            }
        });

    } catch (Exception ex) {
        Log.e(TAG, Constants.GENERAL_ERROR_MESSAGE, ex);
    }
}

Since the Retrofit lib uses the Gson for JSON serialization, I expect the result to be converted to the ApiResponse object on its own. But each time the call fells in the failure block. However, I have verified the same call using the Postman and its returning the correct response.

Body:

{
  "type": "feedback",
  "message": "my new feedback" 
}

Response:

{
    "status": true
}

One more thing to mention here is that there is no authentication required for this call.

Upvotes: 2

Views: 1047

Answers (2)

Lukas Lechner
Lukas Lechner

Reputation: 8191

Retrofit can automatically serialize objects to json (using gson)

=> change your interface to

public interface ISupportApi {
    @Headers({
            "Accept: application/json",
            "Content-type: application/json"
    })
    @POST("/common/feedback")
    void sendFeedback(@Body Feedback feedback, Callback<ApiResponse> callback);
}

and pass your object directly without manual parsing. This should work. Maybe the definition of the headers are obsolet as well, but I am not sure

Upvotes: -1

f.old
f.old

Reputation: 343

You have to use TypedInput:

@POST("/common/feedback")
void sendFeedback(@Body TypedInput feedback, Callback<ApiResponse> callback);

You can convert your Json using something like this:

static TypedInput createRawBodyFromJson(@NonNull String json) {

        try {
            return new TypedByteArray("application/json", json.getBytes(ENCODING_UTF_8));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

Upvotes: 2

Related Questions