美文网首页real安卓开发Android知识
使用retrofit+okhttp+Gson时候服务端成功和失败

使用retrofit+okhttp+Gson时候服务端成功和失败

作者: Avalon1 | 来源:发表于2017-01-05 13:26 被阅读1876次

背景:服务端返回的是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;
}

相关文章

网友评论

  • 挨踢星:打吧,我也支持!😂😂😂
  • 松小白:您好,能否给个完整的代码。我现在也出来这个问题。急急急!!
    Avalon1:@the_lost_key 这个类是com.squareup.retrofit2:converter-gson:2.1.0这个依赖里面的一个Gson处理的类,除了构造方法就只有一个convert方法,就把你传入的T的value转成json吧然后构造一个RequestBody返回
    the_lost_key:弱弱的问下GsonRequestBodyConverter这个是什么样的哈
    Avalon1:你好。其实这个关键的地方只是在CustomResponseConverter这里面的Gson解析之前先用原生的json做了一下判断。按照服务端不同的返回在convert方法里面处理就行了。
  • hfk:😂我更觉得出现这种情况更应该打死后台
    Avalon1:@hfk 哈哈,说来话长,这个问题是我毕业之前遇到得了,只是不怎么写博客记录,有时候遇到又要找,还是自己记录下。已经不在原来的公司了。
    hfk: @Avalon1 😡这种后台就不能宠着
    Avalon1: @hfk 哈哈,也是,明明有个resultinfo字段,他不拿来放提示信息,要放到data我也蛮无语😓。

本文标题:使用retrofit+okhttp+Gson时候服务端成功和失败

本文链接:https://www.haomeiwen.com/subject/hvkzvttx.html