1. 程式人生 > >Rx系列學習筆記_使用okhttp攔截器統一處理返回請求

Rx系列學習筆記_使用okhttp攔截器統一處理返回請求

之前我們進行了一個簡單的請求。但是我們發現api的所以的Observable的型別都是要進行一個ResponseData包裹。ResponseData的程式碼如下:


public class ResponseData<T> {

    private String ErrorCode;
    private String ErrorMsg;
    private String Status;
    private T Data;

    public String getErrorCode() {
        return ErrorCode;
    }

    public
void setErrorCode(String ErrorCode) { this.ErrorCode = ErrorCode; } public String getErrorMsg() { return ErrorMsg; } public void setErrorMsg(String ErrorMsg) { this.ErrorMsg = ErrorMsg; } public String getStatus() { return Status; } public
void setStatus(String Status) { this.Status = Status; } public T getData() { return Data; } public void setData(T Data) { this.Data = Data; } }

結果

 .flatMap(new Func1<ResponseData<CheckDetailsData>, Observable<ResponseData<TyreData>>>() {
                    @Override
public Observable<ResponseData<TyreData>> call(ResponseData<CheckDetailsData> checkDetailsDataResponseData) { return request.getMyApi().getRecordDetail2(checkDetailsDataResponseData.getData().getSerialNumber()); } })

這裡的flatMap中,我們new 的Func1中都是包裹的ResponseData。我們的目標就是使用的時候可以直接返回我們想要的型別。比如這裡我我們想要的是一個CheckDetailsData物件,那我們最終要變成的就是下面這樣的模式,返回的資料我們直接使用不用再去除外層的包裹。

new Func1<CheckDetailsData>, Observable<TyreData>...

1.先在Retrofit請求類中建立一個內部類HttpResultFunc

//用來統一處理Http的resultCode,並將HttpResult的Data部分剝離出來返回給subscriber,這裡的HttpResult就是我們這裡的ResponseData.
private class HttpResultFunc<T> implements Func1<HttpResult<T>, T>{

    @Override
    public T call(HttpResult<T> httpResult) {
        if (httpResult.getResultCode() != 0) {
            throw new ApiException(httpResult.getResultCode());
        }
        return httpResult.getData();
    }
}

2.具體的使用

movieService.getTopMovie(start, count)
            .map(new HttpResultFunc<List<Subject>>())
            .subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(subscriber);

上面的方式也是可以實現資料統一處理請求返回。他的異常什麼的資料都是通過ApiException來處理。但是這裡面在map中會多次去new這個物件,多次請求就會多次去創造。文章的評論下也有人提這個問題,我這個菜雞真的是蒙的,但是沒辦法還得改,他說了一個攔截器,所以我就去查了查,文章還是有的。可以通過Okhttp的攔截器直接攔截處理。

 httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient okHttpClient =new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {

                        Request request = chain.request();
                        //這裡對你自己的Response進行處理後重新返回一個Response
                        Response responseNew=filterResponse(request,chain);
                        return responseNew;
                    }
                })
                .addInterceptor(httpLoggingInterceptor)
                .build();
        retrofitBuild.client(okHttpClient);

參考