retrofit: GsonConverterFactory can not handle String Response

I have the following retrofit code:

Retrofit retrofit = new Retrofit.Builder()
//                .baseUrl("http://10.0.2.2:6543/") // On AVD
                .baseUrl("http://192.168.0.106:6543") // On device
                .addConverterFactory(GsonConverterFactory.create())
                .build();

            EnrollmentRequest = retrofit.create(EnrollmentApiInterface.class);

That makes a POST request:

@Headers({
            "Accept: application/json",
            "Content-Type: application/json"
        })
        @POST("auth/enroll")
        Call<String> RequestEnrollment(@Body EnrollmentRequest EnrollmentDetails);

and is used like:

EnrollmentRequest request = new EnrollmentRequest();
        request.setMsisdn(MsisdnTxt.getText().toString());
        request.setId_number(IdNumberTxt.getText().toString());
        EnrollmentApiClient.EnrollmentApiInterface service = EnrollmentApiClient.getApiClient();
        Log.i(TAG, "REQUEST:   " + request.toJson());
        Call<String> call = service.RequestEnrollment(request);
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Response<String> response) {
                // Create object of SharedPreferences.
                SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(that);
                //now get Editor
                SharedPreferences.Editor editor = sharedPref.edit();
                //put your value
                editor.putString("IDnumber", IdNumberTxt.getText().toString());
                editor.putString("Msisdn", MsisdnTxt.getText().toString());

                //commits your edits
                editor.commit();
                Log.i(TAG, "onClick-AFTER");
                Intent intent = new Intent(getApplicationContext(), AuthoriseActivity.class);
                startActivity(intent);

            }

            @Override
            public void onFailure(Throwable t) {
                // Always get in here
                Log.i(TAG, "NOTHERE", t);
                Log.d("CallBack", " Throwable is " + t.toString());

                Toast.makeText(EnrollActivity.this, "Request Failed", Toast.LENGTH_LONG).show();
            }

The request is sent, but on response I expect a String, but for some odd reason I get the following exception:

 com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 2 path $
            at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1573)
            at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1423)
            at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:575)
            at com.google.gson.stream.JsonReader.peek(JsonReader.java:429)
            at com.google.gson.internal.bind.TypeAdapters$13.read(TypeAdapters.java:349)
            at com.google.gson.internal.bind.TypeAdapters$13.read(TypeAdapters.java:346)
            at com.google.gson.TypeAdapter.fromJson(TypeAdapter.java:256)
            at retrofit.GsonConverter.fromBody(GsonConverter.java:42)
            at retrofit.OkHttpCall.parseResponse(OkHttpCall.java:144)
            at retrofit.OkHttpCall.access$000(OkHttpCall.java:25)
            at retrofit.OkHttpCall$1.onResponse(OkHttpCall.java:90)
            at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:168)
            at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:818)

I have tested Converting The string to Json, using Gson:

Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
                .create();

            String blah = gson.fromJson("\"600\"", String.class);
            Log.w(TAG, blah);

I suspect that this might be a bug in GsonConverterFactory causing this, or am I doing something horribly wrong?

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 20 (4 by maintainers)

Most upvoted comments

I have: ava.lang.IllegalArgumentException: Could not locate ResponseBody converter for class java.lang.String. Tried: .addConverterFactory(ScalarsConverterFactory.create())

compile ‘com.squareup.retrofit2:retrofit:2.0.0-beta3’ compile ‘com.squareup.retrofit2:converter-gson:2.0.0-beta3’ compile ‘com.squareup.retrofit2:converter-scalars:2.0.0-beta3’

compile 'com.squareup.okhttp3:okhttp:3.0.0-RC1'
compile 'com.squareup.okhttp3:logging-interceptor:3.0.0-RC1'

Here’s a link to the updated ToStringConverterFactory: https://github.com/kamilwlf/Kamil-thoughts/blob/master/ToStringConverterFactory.java

@JakeWharton @cbornet @renierdbruyn I used the latest Gson version and it works now:

compile 'com.google.code.gson:gson:2.6.1'

then set the GsonConverterFactory this way:

Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(Constants.SERVICE_URL)
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create(new Gson()))
                    .client(client)
                    .build();

so the solution was in this line

.addConverterFactory(GsonConverterFactory.create(new Gson()))

I imported Gson from the library imported above which is latest version. Make sure it is not imported from Retrofit or the GsonConvertorFactory.

For information, with retrofit 2.0.0-beta3, this issue is worked-around with:

adapterBuilder = new Retrofit.Builder()
               .addConverterFactory(ScalarsConverterFactory.create())
               .addConverterFactory(GsonConverterFactory.create());

I still think that GsonConverterFactory should be able to ser/deser primitive types though…

We use a string converter in all the tests so I can assure you it works. However, it looks like you are using some outdated version of Retrofit 2 as the addConverter API no longer exists. That version might have no behaved correctly with this case, and I would encourage you to use ‘beta2’ or the latest SNAPSHOT instead.

Here’s a link to the ToStringConverterFactory and an example of it being used.

try this:

Gson gson = new GsonBuilder() .setLenient() .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create(gson)) .build();

that’s worked for me.

I still get the MalformedJsonException.