背景:服务端返回的是data,code,info。其中code为0000的时候表示成功。此时data对应正常情况解析json生成的实体类但是当code不为0000的时候,data就是一个String 类型的信息。如果使用官方默认的GSon解析会抛出异常。用rxjava的时候会执行OnError。因为此时类型不匹配。String类型毕竟不是我们自定义的接受json的实体类。
解决方案:不使用retrofit默认的json解析配置,自己参照官方稍微改一下自己写一个(因为官方的那个是final类型的,不允许继承),代码如下 BaseJsonResponse 为自己定义的json对象基类
final class CustomResponseConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private TypeAdapter<T> adapter;
private Type mType;
CustomResponseConverter(Gson gson, TypeAdapter<T> mAdapter, Type mType) {
this.gson = gson;
this.adapter = mAdapter;
this.mType = mType;
}
@Override
public T convert(ResponseBody value) throws IOException {
BaseJsonResponse mResponse = new BaseJsonResponse();
try {
String body = value.string();
JSONObject json = new JSONObject(body);
Log.e("json", "convert: "+body );
String code = json.getString("resultCode");
String msg = json.getString("resultInfo");
if (code.equals("0000")) {
return gson.fromJson(body, mType);
} else {
return (T) mResponse.setResult(json.opt("result")).setResultInfo(msg).setResultCode(code);
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally {
value.close();
}
}}
public final class CustomGsonConverterFactory extends Converter.Factory {
public static CustomGsonConverterFactory create() {
return create(new Gson());
}
public static CustomGsonConverterFactory create(Gson gson) {
return new CustomGsonConverterFactory(gson);
}
private final Gson gson;
private CustomGsonConverterFactory(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 CustomResponseConverter<>(gson, adapter,type);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter adapter = this.gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter(this.gson, adapter);
}
}
然后在创建请求的时候
public ShowApi createShowApi( ) {
if (showApi == null) {
synchronized (RetrofitService.class) {
if (showApi == null) {
initOkHttpClient();
showApi = new Retrofit.Builder()
.client(mOkHttpClient)
.baseUrl(Constant.Host)
.addConverterFactory(CustomGsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build().create(ShowApi.class);
}
}
}
return showApi;
}