liujingxing / rxhttp

🔥🔥🔥 Based on OkHttp encapsulation, support Kotlin Coroutines、RxJava2、RxJava3; 30s to get started.
https://juejin.im/post/5ded221a518825125d14a1d4
Apache License 2.0
3.74k stars 457 forks source link

关于后端接口数据返回null,但是接口成功自定义Parser的问题 #487

Closed LuckyCodeer closed 6 months ago

LuckyCodeer commented 6 months ago

比如有时候后端接口返回{code:200, data: ["1","2"]} 代表成功且有数据

如果无数据,且查询成功会返回 {code:200, data: null} 也就是data 集合是null,这种情况下如果直接用toObservableResponseList 就会报错,

我目前的解决方案是自定义一个Parser 然后里面代码如下

    final Type type = ParameterizedTypeImpl.get(Response.class, List.class, types[0]); //获取泛型类型
    Response<List<T>> data = Converter.convert(response, type);
    List<T> list = data.getData(); //获取data字段
    if (list == null) {
        list = new ArrayList<>();
    }

发现list是null后手动赋值 ,这样去解决的,但是感觉好像不太优雅,请问大佬还有其它更好的解决办法吗?

liujingxing commented 6 months ago

什么意思?你定义了两个Parser? 一个Paser就够了,如果data为null的情况,仍然想走成功回调,如下:

@SuppressWarnings("unchecked")
@Override
public T onParse(@NotNull okhttp3.Response response) throws IOException {
    Response<T> data = Converter.convertTo(response, Response.class, types);
    T t = data.getData(); //获取data字段
    if (t == null) {
        if (types[0] == List.class) {
            t = (T) Collections.emptyList();
        } else if (types[0] == String.class) {
            t = (T) "";
        }//也可以加入其他判断
    }
    if (data.getCode() != 0 || t == null) {//code不等于0,说明数据不正确,抛出异常
        throw new ParseException(String.valueOf(data.getCode()), data.getMsg(), response);
    }
    return t;
}
liujingxing commented 6 months ago

但个人不太喜欢这么干,因为每种对象都写上默认值的话,简直就是个灾难;所以我一般区分两种情况,就是客户端需不需要data字段,详情看文档

liujingxing commented 6 months ago

当然,解析器也可以直接返回Response<T>,也就可以不关心data字段了,如下:

@Parser(name = "Response", wrappers = {PageList.class})
public class ResponseParser<T> extends TypeParser<Response<T>> {

    protected ResponseParser() {
        super();
    }

    public ResponseParser(Type type) {
        super(type);
    }

    @Override
    public Response<T> onParse(@NotNull okhttp3.Response response) throws IOException {
        Response<T> data = Converter.convertTo(response, Response.class, types);
        if (data.getCode() != 0) {//code不等于0,说明数据不正确,抛出异常
            throw new ParseException(String.valueOf(data.getCode()), data.getMsg(), response);
        }
        return data;
    }
}

但是这样的话,成功回调的地方都得手动判断data是否为null

liujingxing commented 6 months ago

解析器不能返回null,是因为RxJava的限制,如果你使用协程,解析器是可以返回null的

LuckyCodeer commented 6 months ago

好的,了解了,谢谢