okhttp请求服务器返回的数据一般是json字符串,我们在哪个地方将字符串转成java对象合适呢
retrofit提供了一个类MyGsonConverterFactory,我们需要重写这个类的一个方法
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new MyGsonResponseBodyConverter<>(type, gson, adapter);
}
然后在Retrofit中设置即可
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.APP_URL_CLIENT_IP_PORT)
.client(configClient())
.addConverterFactory(MyGsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
MyGsonResponseBodyConverter这个类就是把服务器返回值转换java对象
public class MyGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson mGson;
private final TypeAdapter<T> adapter;
private Type type;
public MyGsonResponseBodyConverter(Type type, Gson gson, TypeAdapter<T> adapter) {
this.type = type;
mGson = gson;
this.adapter = adapter;
}
@Override
public T convert(ResponseBody value) throws IOException {
String response = value.string();
if (type instanceof ParameterizedType) {
Log.d("MyGsonResponse" + ((ParameterizedType) type).getActualTypeArguments()[0].toString(), response);
} else {
Log.d("MyGsonResponse" + type.toString(), response);
}
ResultModel<String> re = mGson.fromJson(response, ResultModel.class);
//响应码中负数的情况,一律抛出ApiException异常。
//这样,我们就成功的将该异常交给Observer的onError()方法去处理了。
if (re.getCode() < 0) {
value.close();
throw new ApiException(re.getCode(), re.getMessage());
}
MediaType mediaType = value.contentType();
Charset charset = mediaType != null ? mediaType.charset(UTF_8) : UTF_8;
ByteArrayInputStream bis = new ByteArrayInputStream(response.getBytes());
InputStreamReader reader = new InputStreamReader(bis, charset);
try {
return adapter.fromJson(reader);//将返回值转换为java对象
} finally {
value.close();
}
}
}
上述代码中还涉及到了服务器异常处理,这个看具体情况而定,我们定的规则是code小于0的都是异常,比如-1,是token失效异常。下面是异常处理的一个例子
public abstract class MyObserver<T> implements Observer<T> {
public MyObserver() {
}
@Override
public void onError(Throwable e) {
Type genType = getClass().getGenericSuperclass();
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
Log.e(params[0].toString(), e.toString());
if (e instanceof ApiException){
if (((ApiException) e).getErrorCode()==-1){//重新登录
}
}
}
@Override
public void onCompleted() {
}
}
这个MyObserver在Observable.subscribe()中调用即可
具体例子可以参考https://github.com/lijianjun001/VVMM,