java gson返回值_Retrofit2+Rxjava2 自定义GsonConvert 将Http返回Code状态统一处理

本文介绍了如何通过自定义GsonConverter在Retrofit2和RxJava2中统一处理Http返回Code,隐藏HttpResult结构,使业务层只需关注业务实体。详细讲解了如何构造ParameterizedTypeImpl,修改GsonConverterFactory和GsonResponseBodyConverter,以实现HttpResult对业务Entity的自动包裹和异常处理。
摘要由CSDN通过智能技术生成

这篇文章有提到自定义GsonConvert来统一解析外层包裹的HttpResult关于自定义Code的统一处理,让业务只关心业务实体。

但是这个封装的还不够彻底,业务调用以及Retrofit的定义中还是透明的知道HttpResult的存在。业务调用和Retrofit的API定义应该只关心具体的业务Entity。HttpResult应该是在Gson解析的过程中自动处理,业务处不需要关心和知道它的存在。

那么问题来了,怎么给Entity包裹上HttpResult,变成HttpResult勒。通过断点查看,发现HttpResult的结构在GsonConvert的responseBodyConverter方法中的type 的实际类型是ParameterizedTypeImpl类型的,如下:

571aacda217d

image.png

然后全局搜索ParameterizedTypeImpl 发现

571aacda217d

image.png

于是拷贝retrofit2中的Utils类,简单的走读了一下源码,尽管没太看懂,然后尝试调用api,最后成功的根据Entity和HttpResult,构造出了HttpResult的ParameterizedTypeImpl对象

//给Entity 包裹到HttpResult 的泛型里,成为HttpResult

Utils.ParameterizedTypeImpl parameterizedType =

new Utils.ParameterizedTypeImpl(null, HttpResult.class, typeToken.getType());

拷贝Retrofit2的GsonConverterFactory与GsonRequestBodyConverter、GsonResponseBodyConverter

修改MyGsonConverterFactory的responseBodyConverter方法的传参

public final class MyGsonConverterFactory extends Factory {

private final Gson gson;

public static MyGsonConverterFactory create() {

return create(new Gson());

}

public static MyGsonConverterFactory create(Gson gson) {

if(gson == null) {

throw new NullPointerException("gson == null");

} else {

return new MyGsonConverterFactory(gson);

}

}

private MyGsonConverterFactory(Gson gson) {

this.gson = gson;

}

@Override

public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {

return new GsonResponseBodyConverter(this.gson,TypeToken.get(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);

}

}

修改GsonResponseBodyConverter的构造入参,和泛型定义

final class GsonResponseBodyConverter implements Converter {

private final Gson gson;

private final TypeAdapter> adapter;

GsonResponseBodyConverter(Gson gson, TypeToken typeToken) {

this.gson = gson;

//给Entity 包裹到HttpResult 的泛型里,成为HttpResult

Utils.ParameterizedTypeImpl parameterizedType =

new Utils.ParameterizedTypeImpl(null, HttpResult.class, typeToken.getType());

this.adapter =

(TypeAdapter>) this.gson.getAdapter(TypeToken.get(parameterizedType));

}

@Override

public T convert(ResponseBody value) throws IOException {

JsonReader jsonReader = this.gson.newJsonReader(value.charStream());

HttpResult result;

try {

result = this.adapter.read(jsonReader);

//code!=1,服务器校验返回的错误信息

if (result != null&&result.getCode()!=1){

throw new NetApiException(result.getCode(),result.getMsg());

}

} finally {

value.close();

}

//返回实际的Entity

return result == null ? null : result.getData();

}

}

这样在定义的时候和使用的时候都只知道业务的Entity,而不知道HttpResult的存在。

如:

API定义

public interface LoginApi {

@FormUrlEncoded @POST("lawyer/login") Flowable login(

@Field("user") String phoneNum, @Field("pwd") String password);

}

调用,code异常在异常中判断NetApiException

loginBiz.login(userName, pw)

.compose(RxTransformers.io_main())

.compose(RxTransformers.waitLoadingTransformer(loginView))

.subscribe(new Consumer() {

@Override public void accept(UserEntity userEntity) throws Exception {

Log.i(TAG, "accept: userEntity=" + userEntity.getUserName());

}

}, new Consumer() {

@Override public void accept(Throwable throwable) throws Exception {

if (throwable instanceof NetApiException) {

Log.i(TAG, "accept:登录信息错误 " + throwable.getMessage());

} else {

Log.i(TAG, "accept: " + throwable.getMessage());

}

}

});

附上相关类的定义

public class HttpResult {

private int code;

private String msg;

private T data;

public int getCode() {

return code;

}

public String getMsg() {

return msg;

}

public T getData() {

return data;

}

}

public class NetApiException extends RuntimeException{

private int code;

private String msg;

public NetApiException(int code, String msg) {

this.code = code;

this.msg = msg;

}

@Override public String toString() {

return "Code="+code+" Msg="+msg;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值