美文网首页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