retrofit gson 解析json数据失败问题“com.google.gson.stream.MalformedJsonException:”

来源:互联网 发布:淘宝店铺怎样才能贷款 编辑:程序博客网 时间:2024/05/18 00:08

json服务端返回数据

{'success':'fail'}


retrofit 版本:2.3.0


具体问题:

com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 17 path $.forumbits[0].


问题分析:

通过把上面的json数据拿到网上在线json解析工具中进行校验,json数据校验失败。分析可能是服务器返回的数据中的单引号的问题导致解析失败,一般的json数据返回都是双引号的,gson就认为这个数据格式有问题,json数据格式不严格定义。


问题解决:

通过参考stackoverflow中的一篇文章http://stackoverflow.com/questions/27485346/malformedjsonexception-with-retrofit-api

说是要重写json转换器,本来想着直接用stackoverflow 中的代码,且找不到GsonConverter类,看来行不通了。   且看到了一句代码与错误信息中一样JsonReader.setLenient(true),通过翻译Lenient是宽松的意思,推测就是放宽json检查。



重写转换器:

先分析一下默认的GsonConverter怎么写的, 由三个类组成:

  • GsonConverterFactory // GsonConverter 工厂类, 用来创建GsonConverter
  • GsonResponseBodyConverter // 处理ResponseBody
  • GsonRequestBodyConverter // 处理RequestBody

在重写的GsonResponseBodyConverter的convert方法中添加jsonReader.setLenient(true);


具体代码如下:

public class CustomGsonConverterFactory extends Converter.Factory{    private final Gson gson;    public static CustomGsonConverterFactory create(){        return create(new Gson());    }    private CustomGsonConverterFactory(Gson gson){        this.gson = gson;    }    public static CustomGsonConverterFactory create(Gson gson) {        if (gson == null) throw new NullPointerException("gson == null");        return new CustomGsonConverterFactory(gson);    }    @Nullable    @Override    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));        return new CustomGsonRequestBodyConverter<>(gson, adapter);    }    @Nullable    @Override    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));        return new CustomGsonResponseBodyConverter<>(gson, adapter);    }}

final class CustomGsonRequestBodyConverter<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;    CustomGsonRequestBodyConverter(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);        adapter.write(jsonWriter, value);        jsonWriter.close();        return RequestBody.create(MEDIA_TYPE, buffer.readByteString());    }}

final class CustomGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {    private final Gson gson;    private final TypeAdapter<T> adapter;    CustomGsonResponseBodyConverter(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();        }    }}



阅读全文
3 0
原创粉丝点击