Retrofit2.0 Gets Malformedjsonexception While the JSON Seems Correct

Retrofit2.0 gets MalformedJsonException while the json seems correct?

Finally I solved my problem which is not related to the json lenient mode, something wrong with my POST response (there some other non json output before the json data).

Here is the response from JakeWharton regarding how to set Gson lenient mode:

make sure that you have:compile 'com.google.code.gson:gson:2.6.1'

Gson gson = new GsonBuilder()
.setLenient()
.create();

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

How to get malformed JSON in Retrofit 2

Just log your network responses, so you will see what's wrong.

@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
Log.w("Retrofit@Response", response.body().string());
return response;
}

MalformedJsonException with Retrofit API?

com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) is usually thrown when there is some character(s) that malforms the JSON. Exception message itself suggest to make the deserialization more tolerant.

But I suggest you to fix your JSON and trim it from unwanted characters.

You should extend GsonConverter and override fromBody() to make Gson read from the tolerant JsonReader. Then just set it to your RestAdapter. This will attempt to use tolerant JsonReader to deserialize and then close it, if not exception is thrown.

public class LenientGsonConverter extends GsonConverter {
private Gson mGson;

public LenientGsonConverter(Gson gson) {
super(gson);
mGson = gson;
}

public LenientGsonConverter(Gson gson, String charset) {
super(gson, charset);
mGson = gson;
}

@Override
public Object fromBody(TypedInput body, Type type) throws ConversionException {
boolean willCloseStream = false; // try to close the stream, if there is no exception thrown using tolerant JsonReader
try {
JsonReader jsonReader = new JsonReader(new InputStreamReader(body.in()));
jsonReader.setLenient(true);
Object o = mGson.fromJson(jsonReader,type);
willCloseStream = true;
return o;
} catch (IOException e) {
e.printStackTrace();
}finally {
if(willCloseStream) {
closeStream(body);
}
}

return super.fromBody(body, type);
}

private void closeStream(TypedInput body){
try {
InputStream in = body.in();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

}

Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $

This is a well-known issue and based on this answer you could add setLenient:

Gson gson = new GsonBuilder()
.setLenient()
.create();

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

Now, if you add this to your retrofit, it gives you another error:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $

This is another well-known error you can find answer here (this error means that your server response is not well-formatted); So change server response to return something:

{
android:[
{ ver:"1.5", name:"Cupcace", api:"Api Level 3" }
...
]
}

For better comprehension, compare your response with Github api.

Suggestion: to find out what's going on with your request/response add HttpLoggingInterceptor in your retrofit.

Based on this answer your ServiceHelper would be:

private ServiceHelper() {
httpClient = new OkHttpClient.Builder();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.interceptors().add(interceptor);
Retrofit retrofit = createAdapter().build();
service = retrofit.create(IService.class);
}

Also don't forget to add:

compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'

gson throws MalformedJsonException

I suspect that result1 has some characters at the end of it that you can't see in the debugger that follow the closing } character. What's the length of result1 versus result2? I'll note that result2 as you've quoted it has 169 characters.

GSON throws that particular error when there's extra characters after the end of the object that aren't whitespace, and it defines whitespace very narrowly (as the JSON spec does) - only \t, \n, \r, and space count as whitespace. In particular, note that trailing NUL (\0) characters do not count as whitespace and will cause this error.

If you can't easily figure out what's causing the extra characters at the end and eliminate them, another option is to tell GSON to parse in lenient mode:

Gson gson = new Gson();
JsonReader reader = new JsonReader(new StringReader(result1));
reader.setLenient(true);
Userinfo userinfo1 = gson.fromJson(reader, Userinfo.class);


Related Topics



Leave a reply



Submit