2014-09-25 138 views
8

我正在使用的REST Api具有根據狀態從服務器發送的自定義代碼和消息,我想實現一個自定義Callback<T>,只有在狀態代碼爲自定義錯誤處理與改造

{ 
    "code":"0", 
    "message":"success", 
    "data": { 
    "actual_data":"goes_here", 
    "need_to_construct_objects","from_data" 
    } 
} 

失敗響應的實施例::

從服務器接收到0

實施例成功響應

{ "code":"301", "message":"wrong_password", "data": { "actual_data":"will_be_null", "no_need_to_construct_objects","from_data" } } 

codemessage被所有請求返回時,data包含實際的響應值,所以我想做到以下幾點:

  1. 檢查代碼消息和來電success()如果代碼爲0.
  2. 請致電failure()如果請求失敗或code!= 0
  3. 建設基礎上,數據響應自定義對象,並通過success()

什麼是做到這一點的最佳方式傳遞呢?我到處搜索,找不到一個好的解決方案。我唯一得到的是讓所有自定義對象也有codemessage字段,並檢查它們的值在success()內,但這可能會導致未來出現問題,以免在繼續之前忘記檢查code

+0

其實改造提供了方法來構建自己的自定義錯誤處理程序! – Pavlos 2014-09-25 16:44:31

+0

你能給我一些指點或在哪裏看樣本? – Nima 2014-09-25 16:45:14

+0

http://square.github.io/retrofit/ 「CUSTOM ERROR HANDLING」 – Pavlos 2014-09-25 16:45:46

回答

0

這至少會讓你開始。基本上可以創建自己的自定義回調,然後處理成功。看看發送的內容並做你需要的。

public class CustomCallback implements Callback { 
    @Override 
     public void success(Object o, Response response) { 

       //Check for success 
       //if(Success) 
       //callback.success(o, response); 
       //else 
       //Check for error 
       //callback.failure(error); 


     } 
    } 
3

只需製作一個實現回調的抽象類,然後聲明自己的抽象成功和失敗方法,就可以快速完成該任務。抽象類將處理Retrofit的標準回調方法,解釋響應並相應地調用抽象方法。

我認爲另一種可能的方法是覆蓋Retrofit的客戶端接口來構建自己的Response對象。

如果擴展OkClient,它可以是這樣的:

public class CustomClient extends OkClient { 

    @Override public Response execute(Request request) throws IOException { 
      Response originalRespone = super.execute(request); 

      int statusCode = 0; 
      //TODO: read JSON response here (using GSON or similar, and extract status code and message... etc.) 

      //Convert the status code to HTTP standard status codes, according to the documentation you have. 
      if(statusCode == 0) statusCode = 200; 
      //Reconstruct a Response object 
      return new Response(originalResponse.getUrl(), statusCode, originalResponse.getReason() /*should probably replace with parsed message*/, originalResponse.getHeaders(), originalResponse.getBody()); 
    } 

這可能比在回調處理,你的情況更多的工作,但我認爲它可以幫助,如果在某一時刻的API轉換爲REST的API約定。

儘管這個解決方案有自己的問題,因爲這意味着JSON轉換將運行兩次。一個在你的客戶端,另一個由Retrofit完成。不確定此刻正確的做法。可能是TypedInput周圍的東西,還有一個虛擬轉換器,它可以傳遞已經轉換好的對象。

0

在你的情況,你可以有你的映射JSON響應類:

class CustomResponse { 
    String code; 
    String message; 
    Data data; 

    static class Data { 
    String actualData; 
    String needToContructObjects; 
    String noNeedToContructObjects; 
    } 
} 

然後,因爲你回到java對象的世界裏,你可以有你的成功的內部工廠狀物體方法回調,它基於返回的自定義響應創建所需的對象。如果你想在失敗回調中得到這個響應,我會重新考慮使用Retrofit,因爲你的API沒有遵循好的Rest設計。

雖然這是很多可能的,理解你可能不參與對API的開發,要知道這是不是一個很好的API的設計方法。如果您正在向服務器發送登錄請求,則可以將此請求理解爲創建資源的請求(例如經過身份驗證的用戶會話)。如果不發送正確的參數(在這種特殊情況下正確的用戶名和密碼),服務器應該拒絕的資源創建請求並返回一個4一百東西(4XX)HTTP狀態代碼,表明你的要求是不正確不知何故。改造會理解這個4xx狀態碼,並調用你的失敗回調函數,在那裏你可以適當地處理響應。

1

創建自定義ResponseBodyConverter這樣的:

public class CustomResponseBodyConverter<T> implements Converter<ResponseBody, T> { 
private final TypeAdapter<T> adapter; 

CustomResponseBodyConverter(TypeAdapter<T> adapter) { 
    this.adapter = adapter; 
} 

@Override 
public T convert(ResponseBody value) throws IOException,CustomException { 
    String json = ""; 
    try { 
     String body = value.string(); 
     json = new JSONObject(body).getJSONObject("data").toString(); 
     int code = new JSONObject(body).getInt("code"); 
     String message = new JSONObject(body).getString("message"); 
     if(code != 0){ 
      throw new CustomException(message); 
     } 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
    return adapter.fromJson(json); 
    } 
} 
+0

這與改造如何使用 – taotao 2017-01-06 09:15:29

0

這是實現一個自定義的回調更好的主意。你可以在下面舉個例子。

public abstract class DefaultRequestCallback<T> implements Callback<T> { 

    public abstract void failure(Meta meta); 

    public abstract void success(T responseBean); 

    @Override 
    public void success(T baseResponseBean, Response response) { 
     // You can check your responsebean's error code and 
     // convert it to a default error 
     BaseResponseBean bean = (BaseResponseBean) baseResponseBean; 
     if (bean == null) { 
      failure(new Meta(ApplicationConstants.ERROR_RETROFIT, "Unknown Error!")); 
     } else if (bean.getMeta() != null && bean.getMeta().getCode() != ApplicationConstants.RESULT_SUCCESS) { 
      failure(bean.getMeta()); 
     } else { 
      success(baseResponseBean); 
     } 
    } 

    @Override 
    public void failure(RetrofitError error) { 
     // Convert default error to your custom error. 
     Meta meta = new Meta(ApplicationConstants.ERROR_RETROFIT, "Error Unknwon"); 
     failure(meta); 
    } 
} 

將您的自定義回調賦予您的改進服務接口方法。

void yourMethod(DefaultRequestCallback<YourResponseBean> callback); 

祝你好運。