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
How to Add Shadow to the Fab Provided with the Android Support Design Library
Notifications Fail to Display in Android Oreo (API 26)
Android Viewpager Setcurrentitem Not Working After Onresume
How to Add a Gesture Detector to a View in Android
Android Xml VS Java Layouts Performance
How to Upload File Using Volley Library in Android
Display All Unicode Chars in Textview
Fragment-Fragment Communication in Android
Resource Linking Fails on Lstar
Difference Between Finish() and System.Exit(0)
Android/Java: Transition/Migration from Proguard to R8
Limit Scrolling and Zooming Google Maps Android API V2
How to Hide System Bar on Android Ics
No Network Security Config Specified, Using Platform Default - Android Log
Android Image View Matrix Scale + Translate
Android Splash Screen Sizes for Ldpi,Mdpi, Hdpi, Xhdpi Displays? - Eg:1024X768 Pixels for Ldpi