前情提示: 本文只是一個例子,不做過多講解,入門知識推薦參考 仍物線大神講解的Rxjava,如何優雅的處理服務器異常,本文沒有對Rxjava進行任何封裝,也沒有使用retrolambda,因為對于初學者來說,看起來費(不)勁(會),而且也沒必要。 另外你可以直接看總結,當然如果你只想了解如何處理異常。
正文 今天要寫的例子是模擬 一個實際的登錄請求。 1. 用戶登錄 2. 根據用戶登錄的返回結果(Status code),判斷是否繼續執行 查詢用戶
開始 1. 首先定義Services接口 public interface IUserServices {
@POST("user/login")@FormUrlEncodedObservable<ResponseBody> login(@Field("acount")String acount, @Field("passWord") String password);@GET("user/{userid}")Observable<JsonResponse<User>> getUserById(@Path("userid")String userid);}
配置我們的OkHttpClientOkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new LogingInterceptor()) .retryOnConnectionFailure(true) .addInterceptor(responselog) .addNetworkInterceptor(new TokenInterceptor()) .build();配置Retrofit mRetrofit = new Retrofit.Builder() .baseUrl(ConstandUtils.SERVICE_BASEURL) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .client(client) .build();自定義返回對象public class JsonResponse<T> { PRivate int status; //狀態碼 status_code private T data; public int getStatus_code() { return status; } public void setStatus_code(int status_code) { this.status = status_code; } public T getData() { return data; } public void setData(T data) { this.data = data; }}關于這個對象,是為了結構化的Json而封裝的實體,起初我的Services接口中的接口是這么寫的:
@GET("user/{userid}") Observable<User> getUserById(@Path("userid")String userid);可是當我發現轉換的實體對象的值全為null的時候:
{id='null', acount='null', name='null', email='null', emailConfirmed='null'....}我注意了下 服務器所返回的json字符串:
{"status":0,"data":{"id":null,"acount":"xxxxxxxxx","name":null,"email":null,"emailConfirmed":null,"isLocked....當然現在的后臺返回的數據大部分都是結構化的,所以這個問題只是當時我沒注意引起的。
開始請求mUserService=mRetrofit.create(IUserServices.class);mIUserServices .login(username,pwd) //登錄請求,傳入用戶名和密碼,返回Observable<ResponseBody> 對象 .subscribeOn(Schedulers.io()) //事件產生在io線程 .flatMap(new Func1<ResponseBody, Observable<JsonResponse<User>>>() { @Override public Observable<JsonResponse<User>> call(ResponseBody responseBody) { String userid = parse_Login(responseBody); //解析這個Response(相當于在解析 json),得到userid if("error".equals(userid)) { //status code >0 返回error,表示請求有誤 return Observable.error(new Throwable("信息錯誤"));//隨便返回了一個錯誤信息 } return mIUserServices.getUserById(userid); //如果有,證明請求成功,那么去查詢用戶 } }) .flatMap(new Func1<JsonResponse<User>, Observable<User>>() { @Override public Observable<User> call(JsonResponse<User> userJsonResponse) { return Observable.just(userJsonResponse.getData()); //將這個user發送出去 } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<User>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { mPresenter.onError(e.getMessage()); } @Override public void onNext(User user) { System.out.println("--->user"+user); } });重點內容
當使用map時候,你就不能使用 Observable.error()了,它會繼續往下執行,從而無法中斷這次鏈式。你需要使用 throw new 一個異常當使用flatmap時候,你要使用Observable.error()就這樣。一個成功的嵌套請求+優雅的對Status code處理示例
新聞熱點
疑難解答