报错信息:com.google.gson.JsonSyntaxE
2019-01-05 本文已影响32人
蘑菇v5
【声明:】本文是作者(蘑菇v5)原创,版权归作者 蘑菇v5所有,侵权必究。本文首发在简书。如若转发,请注明作者和来源地址!未经授权,严禁私自转载!
一、问题:
![](https://img.haomeiwen.com/i2658915/7b3f582543f186f3.png)
二、原因:
Gson
解析异常,出现这个的原因多是接口返回值Gson
串不规范、不标准,甚至是返回乱码,这些都需要后台去处理(JSON
数据有没有多余的空格)。
测试时,可以通过把上面的json
数据拿到网上在线json解析
工具中进行校验,可以发现json
数据校验失败。
三、stackoverflow解答:
四、推荐代码:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://whatever.com")
.addConverterFactory(LenientGsonConverterFactory.create(gson))
.build();
public final class LenientGsonConverterFactory extends Converter.Factory {
/**
* Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
public static LenientGsonConverterFactory create() {
return create(new Gson());
}
/**
* Create an instance using {@code gson} for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
public static LenientGsonConverterFactory create(Gson gson) {
return new LenientGsonConverterFactory(gson);
}
private final Gson gson;
private LenientGsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new LenientGsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new LenientGsonRequestBodyConverter<>(gson, adapter);
}
}
private class LenientGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
LenientGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
jsonReader.setLenient(true);
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}
}
private class LenientGsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson gson;
private final TypeAdapter<T> adapter;
LenientGsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public RequestBody convert(T value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
JsonWriter jsonWriter = gson.newJsonWriter(writer);
jsonWriter.setLenient(true);
adapter.write(jsonWriter, value);
jsonWriter.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}