0

I am having troubles doing a POST request with retrofit 2. I am attempting to POST using Retrofit's GsonConverterFactory to convert a POJO object into JSON.

I have GET requests to work with the GsonConverterFactory converting the body into a POJO class, but on a POST it doesn't seem to work (POJO to JSON). I am using this in Android Studio and use Gradle to build my project. These are my Gradle dependencies:

compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.okhttp:okhttp:2.7.5'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.1'

Here is my code for the Api Interface:

public interface EhabrApi {
    @POST("/create-account")
    Call<ResponseBody> createUser(@Body User user);
}

And this is the code to make the request:

    User newUser = new User("Bob", "Smith", "bob@gmail.com", "password", "Seattle", "1990-01-01");

    System.out.println("User is " + new Gson().toJson(newUser));

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(API_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    EhabrApi ehabrApi = retrofit.create(EhabrApi.class);
    Call<ResponseBody> call = ehabrApi.createUser(newUser);
    System.out.println("Request is " + new Gson().toJson(call.request()));

    call.enqueue(new Callback<ResponseBody>() {
           @Override
           public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
               int statusCode = response.code();
               System.out.println("Recieved " + statusCode);
           }

           @Override
           public void onFailure(Call<ResponseBody> call, Throwable t) {
               System.out.println("Failed call " + t);
               System.out.println("stack trace: ");
               t.printStackTrace();
           }
        }
    );

Here is my output and the stack trace:

Creating new account
User is {"Birthday":"1990-01-01","City":"Seattle","Email":"bob@gmail.com","FirstName":"Bob","LastName":"Smith","Password":"password"}
Request is {"headers":{"namesAndValues":[]},"method":"POST","url":{"host":"mywebpage.com","password":"","pathSegments":["create-account"],"port":8080,"scheme":"http","url":"http://mywebpage.com","username":""}}
Failed call com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $
stack trace: 
com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $
    at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1567)
    at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1416)
    at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:597)
    at com.google.gson.stream.JsonReader.peek(JsonReader.java:429)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:201)
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
    at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:116)
    at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
    at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:106)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)

EDIT: Now I have put in an interceptor as suggested. The POST request looks right to me... Here it is:

--> POST http://[mywebpageurl.com]/create-account http/1.1
Content-Type: application/json; charset=UTF-8
Content-Length: 125
{"Birthday":"1990-01-01","City":"Seattle","Email":"bob@gmail.com","FirstName":"Bob","LastName":"Smith","Password":"password"}
--> END POST (125-byte body)
<-- 200 OK http://[mywebpageurl.com]/create-account (100ms)
  • It looks like the JSON that is being returned from your service is what's malformed, not your request. Are you able to see what your call is returning? – Alex Townsend Apr 05 '16 at 20:26
  • Yeah I think you're right. However I'm hitting the onFailure method not onResponse method in my callback, so only have access to a Call object, which doesn't have any methods for getting the response, just the request. – Devan Carlson Apr 05 '16 at 20:29
  • I would look into adding a [OkHttp LoggingInterceptor](https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor). Setting the `LogLevel` to `LogLevel.BODY` should let you see what your response is before it gets to your converters. – Alex Townsend Apr 05 '16 at 20:31
  • I just editted my post with doing what you suggested. It looks right to me... – Devan Carlson Apr 05 '16 at 20:49
  • Possible duplicate of [MalformedJsonException with Retrofit API?](http://stackoverflow.com/questions/27485346/malformedjsonexception-with-retrofit-api) – Gueorgui Obregon Apr 05 '16 at 20:51
  • Check this answer http://stackoverflow.com/a/27698866/4848308 – Gueorgui Obregon Apr 05 '16 at 20:51
  • @DevanCarlson is there anything after the `<-- 200 OK` in the log? That would be where your response and the response body is logged. – Alex Townsend Apr 05 '16 at 20:55
  • The problem actually ended up being in my backend. The problem is solved. The code I have works. Thanks for the debugging help @AlexTownsend! – Devan Carlson Apr 07 '16 at 05:31
  • See this post : [http://stackoverflow.com/questions/35984898/retrofit2-0-gets-malformedjsonexception-while-the-json-seems-correct](http://stackoverflow.com/questions/35984898/retrofit2-0-gets-malformedjsonexception-while-the-json-seems-correct) – nekiala Sep 22 '16 at 07:41

1 Answers1

0

It is so clear in your logcat message

Failed call com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $

So it means you waits JSONObject but as a result of your request you are getting Malformed JSONObject. To solve problem please check your JSON response.

Emin Ayar
  • 1,104
  • 9
  • 13