美文网首页
Retrofit Gson转换异常 begin array

Retrofit Gson转换异常 begin array

作者: glory辉 | 来源:发表于2018-06-11 14:39 被阅读0次

    最近跟朋友在一起吃饭,发现现在很多人都已经在用retrofit 来做为网络请求框架!谈到其中一个问题就是跟后台的沟通问题,我以前的项目后台返回给我的数据都是按照这样返回给我的: 如果正常返回result 对应的是一个jsonArray, 如果返回的错误信息,result 对应的就是一个空的数组,而不是返回给我的json对象!,这样来说,retrofit 解析是完全没有问题的,也就是说你的bean 的结构是什么样,就必须要后台按照那个结构给你 -----------

    后来新项目,后台新架构,对,问题出现了,对的 ,就是大家看到的这个错误

    begin array but was object

    而且后台直接拒绝以前后台的做法,原因是他们有一个拦截器,错误信息直接给你拦截掉了,哈哈,尴尬了,拦截器是统一的,改的成本太大,so ,自己想办法吧 ,也是百度,google了一番,最后也是找到了这样一种解决方案:再retrofit拿到response 之后,拦截判断一下.如果是正常的response code 就直接放行,如果不是,就直接抛出一个自定义的异常类,这个异常类包含errorCode,和errorMsg ,对的,这些已经够我们用了!下面上代码,为了让其他人少走弯路就直接把代码贴上了,直接拿走,不要客气!

    首先上正常用retrofit创建

    4262301-cc06555ef7134628.png

    这个我就上图片了,因为你们也用不到,我们就是从GsonConverterFactory入手,需要自定义一个转换器

    CustomGsonConverterFactory

    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));
    //返回一个自定义的ResponseConverter   重点都在这里面
            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));
    //返回一个自定义的RequestBodyConverte   这个就直接把retrofit 的GsonConverterFactory 里面的RequestBodyConverte   复制过来到自己的定义的类就行了
            return new GsonRequestBodyConverter(this.gson, adapter);
        }
    }
    

    从上面注释大家也就知道了,重点是CustomResponseConverter ,因为所有的处理逻辑都在里面,下面贴这个类的代码,有兴趣的可以看下源码,对比下自定义和源码的区别

    CustomResponseConverterimplements

    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 {
    
            ErrorResponse errorResponse = new ErrorResponse();
            try {
                String body = value.string();
                JSONObject json = new JSONObject(body);
                String code = json.getString("respCode");
                String msg = json.getString("respMsg");
                if (Constant.RESPCODE.equals(code)) {
    //此处的RESPCODE为你和后台约定返回的正常的responseCode
                    return gson.fromJson(body, mType);
                } else {
                    errorResponse = gson.fromJson(body, ErrorResponse.class);
                    //ErrorResponse  为自定义的错误类
                    //抛一个自定义ResultException 传入失败时候的状态码,和信息
                    throw new ResultException(errorResponse.getRespCode(), errorResponse.getRespMsg());
                }
            } catch (Exception e) {
                throw new ResultException(errorResponse.getRespCode(), errorResponse.getRespMsg());
            } finally {
                value.close();
            }
    
        }
    }
    

    自定义的CustomGsonConverterFactory所需要的元素都已经到位了,下面就是替换掉原生的GsonConverterFactory


    4262301-ac7e26b28bc298d2.png

    OK小伙伴们,就是这么简单,为了小伙伴更轻松的解决问题,我把所需要的类,都贴在下面,是不是懂你呢
    ErrorResponse

    public class ErrorResponse {
    
    
        public ErrorResponse(){
            this.respCode= "";
            this.respMsg="";
        }
    
    
        /**
         *
         */
        private String respCode;
    
        /**
         *
         */
        private String respMsg;
    
        public String getRespCode() {
            return respCode;
        }
    
        public void setRespCode(String respCode) {
            this.respCode = respCode;
        }
    
        public String getRespMsg() {
            return respMsg;
        }
    
        public void setRespMsg(String respMsg) {
            this.respMsg = respMsg;
        }
    
        @Override
        public String toString() {
            return "ErrorResponse{" +
                    "respCode='" + respCode + '\'' +
                    ", respMsg='" + respMsg + '\'' +
                    '}';
        }
    }
    
    

    自定义的 ResultExceptionextends

    public class ResultExceptionextends RuntimeException {
    
    private StringrespMsg;
    
        private StringrespCode;
    
        public ResultException(String respCode, String respMsg) {
    
    this.respMsg = respMsg;
    
            this.respCode = respCode;
    
        }
    
    public StringgetRespMsg() {
    
    return respMsg;
    
        }
    
    public void setRespMsg(String respMsg) {
    
    this.respMsg = respMsg;
    
        }
    
    public StringgetRespCode() {
    
    return respCode;
    
        }
    
    public void setRespCode(String respCode) {
    
    this.respCode = respCode;
    
        }
    
    }
    
    

    OK 到此结束!

    相关文章

      网友评论

          本文标题:Retrofit Gson转换异常 begin array

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