以前一直使用OkHttp作为网络请求,想多了解几种不同网络的框架,不奢求精通,只想先开始学习和使用。
最近在学习Retrofit这个东西,可能各位同学已经相当熟练的掌握了Retrofit和RxJava的使用,无奈本人太菜,本着贪多嚼不烂的原则,去使用Retrofit。RxJava还没一起。
初步使用,正在学习阶段。可是当去解析后台接口返回数据的时候,需要先定义自己接收的类型,才能拿到数据。而且同一位置不同数据格式的情况下,原本的解析会出现问题。。明明是请求接口成功,可是总会走onFailure方法。去网上查查资料,原来是Converter的问题。需要自定义Converter来解决。先上图格式不同的Json吧:
成功返回:{
"code": 0,
"msg":"个人信息查询成功",
"data":{
"default_status": 1,
"province_id": 1,
"city_id": 35,
}
}
失败返回:
{
"code": 203,
"msg": "查询失败",
"data": {}
}
一个data让我在使用Retrofit解析的时候惊恐万分,虽说让后台修改数据格式可以解析,不过时间充沛,自己死磕一下,应该可以解决。
想法: 如果失败的时候data是没有数据的,那么我在请求失败,解析的时候不去解析data的数据,直接解析code,和msg不就好了。
实现:根据资料查到,Retrofit的解析是就是转换器来控制的,也就是下图所示:
那么自己写个算了:
重点不是这里,因为是解析的问题,就是response的问题:
public class DecodeResponseBodyConverter<T extends BaseResponse> implements Converter<ResponseBody,T> {
private final Gson gson;
private final Type type;
DecodeResponseBodyConverter(Type type,Gson gson) {
this.gson= gson;
this.type= type;
}
@Override
public T convert (ResponseBody value) throws IOException {
String response = value.string();
JsonObject jsonObject =newJsonParser().parse(response).getAsJsonObject();
// 解析code
JsonPrimitive jsonPrimitive = jsonObject.getAsJsonPrimitive("code");
intcode =0;
if(jsonPrimitive !=null) {
code = jsonPrimitive.getAsInt();
}
// 解析message
JsonElement jsonElement = jsonObject.get("msg");
String message =null;
if(jsonElement !=null) {
message = jsonElement.getAsString();
}
Tt =null;
try{
// 通过反射获取泛型的实例对象
Class clazz = (Class)type;
t = clazz.newInstance();
}catch(Exception e) {
e.printStackTrace();
}
if(code !=0) {
//不解析data数据,直接使code和message返回
t.code= code;
t.msg= message;
}else{
// 按标准格式解析
return gson.fromJson(response,type);
}
returnt;
}
}
这样就实现的我的需求。。。。
BaseResponse 就是自己定义的code msg ,每个接口返回的公共参数,data数据不明确,让子类去继承BaseResponse。
RequestBodyConverter是吧retrofit的当中RequestBodyConverter源码复制了一份,因为retrofit不让用。。
各位有更好,更华丽的解决方案,欢迎讨论。