zhou-you / RxEasyHttp

本库是一款基于RxJava2+Retrofit2实现简单易用的网络请求框架,结合android平台特性的网络封装库,采用api链式调用一点到底,集成cookie管理,多种缓存模式,极简https配置,上传下载进度显示,请求错误自动重试,请求携带token、时间戳、签名sign动态配置,自动登录成功后请求重发功能,3种层次的参数设置默认全局局部,默认标准ApiResult同时可以支持自定义的数据结构,已经能满足现在的大部分网络请求。
Apache License 2.0
3.13k stars 615 forks source link

服务器返回数据的解析(ApiResultFunc<T>)是一个一直未被解决的槽点 #232

Open zhumj opened 3 years ago

zhumj commented 3 years ago

可以根据ApiResult.isOk()判断解不解析data,当请求失败的时候data返回一个默认的 T,这样就可以解决请求成功和请求失败的时候服务器返回的data数据不一样导致Gson解析报错的问题。

zhumj commented 3 years ago

这是我改造之后的数据解析类,一定程度上解决了请求成功和失败的时候,data返回不同类型的问题,例如: 成功时 { code: 0, msg: "请求成功", data: {...json数据...} } 失败时 { code: 0, msg: "请求失败", data: “null” }

解析类

public class ApiResultFunc<T> implements Function<ResponseBody, ApiResult<T>> {
    protected Type type;
    protected Gson gson;

    public ApiResultFunc(Type type) {
        gson = new GsonBuilder()
                .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC)
                .serializeNulls()
                .create();
        this.type = type;
    }

    @Override
    public ApiResult<T> apply(@NonNull ResponseBody responseBody) throws Exception {
        ApiResult<T> apiResult = new ApiResult<>();
        apiResult.setCode(-1);

        try {
            String json = responseBody.string();
            final ApiResult result = parseApiResult(json, apiResult);

            if (result == null) {
                apiResult.setMsg("data is null");
            } else {
                apiResult.setCode(result.getCode());
                apiResult.setMsg(result.getMsg());

                final Class<T> clazz = Utils.getClass(type, 0);
                //增加是List<String>判断错误的问题
                if (apiResult.isOk()) {
                    if (!List.class.isAssignableFrom(clazz) && clazz.equals(String.class)) {
                        apiResult.setData((T) json);
                        apiResult.setCode(0);
                    } else {
                        apiResult = gson.fromJson(json, type);
                    }
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
            apiResult.setMsg(e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            apiResult.setMsg(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            apiResult.setMsg(e.getMessage());
        } finally {
            responseBody.close();
        }
        return apiResult;
    }

    private ApiResult parseApiResult(String json, ApiResult apiResult) throws JSONException {
        if (TextUtils.isEmpty(json))
            return null;
        JSONObject jsonObject = new JSONObject(json);
        if (jsonObject.has("code")) {
            apiResult.setCode(jsonObject.getInt("code"));
        }
        if (jsonObject.has("data")) {
            apiResult.setData(jsonObject.getString("data"));
        }
        if (jsonObject.has("msg")) {
            apiResult.setMsg(jsonObject.getString("msg"));
        }
        return apiResult;
    }
}