关于Retrofit返回错误信息的统一解决办法
来源:互联网 发布:大数据的前沿技术培训 编辑:程序博客网 时间:2024/05/16 14:32
最近哥们儿遇到的一个棘手难题,关于Retrofit请求的处理,一开始我觉得这种一般简单,根据返回code来就行,框架都给封装好了啊,之后自己上手之后才发现有些还是需要处理的。
问题如下图所示:
我来解释一下,Call里面的泛型和返回的对应不上,但是还是会走成功,同时response.isSuccess()为tue,对象里面的属性全是null(很好理解,因为JavaBean根本对应不上啊),奇怪的是Gson并没有抛错,郁闷,所以我们就只能手动处理这些异常了!
首先特别感谢博主的文章Retrofit统一处理服务器返回参数,这篇文章已经非常完整详细地讲解了Retrofit的相关处理办法,只是苦于木有Demo,我这边自己写Demo的时候还遇到了一个坑,就是没有办法收到异常,最终发现原来是Exception继承的问题,我一开始继承了Exception,后来才发现RunTimeException才可以中断之后的操作,所以修改如下。
package com.marsjiang.myretrofiterrortest.expection;/** * Created by Jiang on 2017-09-28. */public class MyException extends RuntimeException { public MyException(){ super(); } public MyException(String msg){ super(msg); }}返回消息类和原博主保持一致:
package com.marsjiang.myretrofiterrortest.bean;/** * Created by Jiang on 2017-09-28. */public class Result<T> { private int state; private String msg; private T data; public int getState() { return state; } public void setState(int state) { this.state = state; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getData() { return data; } public void setData(T data) { this.data = data; }}
下面来介绍其他的主要类(具体的讲解大家可以参考上篇博主的文章,写的非常棒,我就不啰嗦了):
MyGsonConverterFactory
package com.marsjiang.myretrofiterrortest.myretrofit;import com.google.gson.Gson;import com.google.gson.TypeAdapter;import com.google.gson.reflect.TypeToken;import java.lang.annotation.Annotation;import java.lang.reflect.Type;import okhttp3.RequestBody;import okhttp3.ResponseBody;import retrofit2.Converter;import retrofit2.Retrofit;/** * Created by Jiang on 2017-09-28. */public final class MyGsonConverterFactory extends Converter.Factory { /** * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and * decoding from JSON (when no charset is specified by a header) will use UTF-8. */ public static MyGsonConverterFactory create() { return create(new Gson()); } /** * Create an instance using {@code gson} for conversion. Encoding to JSON and * decoding from JSON (when no charset is specified by a header) will use UTF-8. */ public static MyGsonConverterFactory create(Gson gson) { return new MyGsonConverterFactory(gson); } private final Gson gson; private MyGsonConverterFactory(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 MyGsonResponseBodyConverter<>(gson, adapter); } @Override public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); return (Converter<?, RequestBody>) new MyGsonResponseBodyConverter<>(gson, adapter); }}
MyGsonResponseBodyConverter:
package com.marsjiang.myretrofiterrortest.myretrofit;import com.google.gson.Gson;import com.google.gson.TypeAdapter;import com.google.gson.stream.JsonReader;import com.marsjiang.myretrofiterrortest.bean.Result;import com.marsjiang.myretrofiterrortest.expection.MyException;import java.io.IOException;import java.io.StringReader;import okhttp3.ResponseBody;import retrofit2.Converter;/** * Created by Jiang on 2017-09-28. */final class MyGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> { private final Gson gson; private final TypeAdapter<T> adapter; private static final int FAILURE = 0; // 失败 提示失败msg private static final int SUCCESS = 1; // 成功 private static final int TOKEN_EXPIRE = 2; // token过期 private static final int SERVER_EXCEPTION = 3; // 服务器异常 MyGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; } @Override public T convert(ResponseBody value) throws IOException { JsonReader jsonReader = gson.newJsonReader(value.charStream()); String json = value.string(); try { verify(json);// return adapter.read(jsonReader); return adapter.read(gson.newJsonReader(new StringReader(json))); } finally { value.close(); } } private void verify(String json) { Result result = gson.fromJson(json, Result.class); if (result.getState() != SUCCESS) { int a = result.getState(); switch (result.getState()) { case SERVER_EXCEPTION: throw new MyException(result.getMsg()); case TOKEN_EXPIRE: throw new MyException(result.getMsg()); default:// throw new MyException("不清楚什么原因!"); } } }}
这样抛出来的异常就可以被retrofit的onFailure()方法接收到了!关于异常的code大家自己去和服务端定好就行!
在MainActivity中,我添加了一个okhttp过滤器,旨在监听每个请求,并将其打印出来,前提是大家需要导入一个第三方:
compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
下面是完整代码:
package com.marsjiang.myretrofiterrortest;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import com.marsjiang.myretrofiterrortest.bean.Result;import com.marsjiang.myretrofiterrortest.bean.UserReturnBean;import com.marsjiang.myretrofiterrortest.myretrofit.MyGsonConverterFactory;import okhttp3.OkHttpClient;import okhttp3.logging.HttpLoggingInterceptor;import retrofit2.Call;import retrofit2.Callback;import retrofit2.Response;import retrofit2.Retrofit;public class MainActivity extends AppCompatActivity { private Retrofit retrofit; private String ipPortString; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ipPortString = "192.168.10。19:8080"; String url = "http://" + ipPortString + "/XiaoXiao/"; retrofit = new Retrofit.Builder() .baseUrl(url) .addConverterFactory(MyGsonConverterFactory.create()) .client(getOkHttpClient()) .build(); ApiCore userBiz = retrofit.create(ApiCore.class); Call<Result<UserReturnBean>> call = userBiz.getLoginInfo(); call.enqueue(new Callback<Result<UserReturnBean>>() { @Override public void onResponse(Call<Result<UserReturnBean>> call, Response<Result<UserReturnBean>> response) { if (response.isSuccessful()) { if (response.body().getData() == null) { } Log.e("infoooo", "normalGet:" + response.body() + ""); } } @Override public void onFailure(Call<Result<UserReturnBean>> call, Throwable t) { Log.e("infoooo", "normalGet:" + t.toString() + ""); } }); } /** * 获取okhttp拦截器 * * @return */ public OkHttpClient getOkHttpClient() { //日志显示级别 HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY; //新建log拦截器 HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { @Override public void log(String message) { Log.d("zcb", "OkHttp====Message:" + message); } }); loggingInterceptor.setLevel(level); //定制OkHttp OkHttpClient.Builder httpClientBuilder = new OkHttpClient .Builder(); //OkHttp进行添加拦截器loggingInterceptor httpClientBuilder.addInterceptor(loggingInterceptor); return httpClientBuilder.build(); }}
嗯,这样每次就能打印出来了!
代码是最好的老师!
gitHub地址:
点击打开链接
还是那句话,做好自己,加油!
阅读全文
0 0
- 关于Retrofit返回错误信息的统一解决办法
- retrofit数据返回类型不统一解析方法
- Rxjava +Retrofit 你需要掌握的几个技巧,Retrofit缓存,RxJava封装,统一对有无网络处理,异常处理, 返回结果问题
- AFNetworking 返回的错误信息 总结
- 关于错误信息的显示
- 关于子函数返回指针的解决办法
- 关于Retrofit的理解之Hello Retrofit
- 关于微信企业付款(提现)返回错误信息的调试
- Tomcat 启动和关闭时关于Apache Portable Runtime的错误信息解决办法
- 关于数据库连接出错(错误信息:[无法加载dll(oci.dll)])的解决办法
- Tomcat 启动和关闭时关于Apache Portable Runtime的错误信息解决办法
- Spring Boot实战之全局异常捕获 实现参数异常检查返回统一错误信息
- RxJava结合Retrofit对网络请求结果的统一处理
- retrofit&rxjava&gson请求成功后回调的统一处理
- ERROR_MESSAGE返回@@error对应的错误信息
- 如何知道GetLastError()返回的错误信息
- 如何获取ffmpeg返回的错误信息
- AFNetworking打印输出服务器返回的错误信息
- centos访问Windows共享文件两种方式:
- Qualcomm Simlock——解锁流程
- Android属性动画个人小结
- Android 中 C++ Thread线程用法
- Struts2框架
- 关于Retrofit返回错误信息的统一解决办法
- 从搭建环境到一个简单Android App测试实例
- [codevs1183]泥泞的道路(二分+正环)
- 安卓配置正式包和测试包不同的名字、图标、同时安装,(极光配置测试和正式)
- ETL学习笔记之实现
- 使用OkhttpUtils作为网络框架同时,使用Glide加载Https图片
- 图像语义分割常用数据库
- 机器学习笔记三
- JQuery中$.ajax()方法参数详解