2017-06-16 92 views
1

我正在將Retrofit 2引入到我們的一個新項目中。當我使用Retrofit來使用Web服務響應時,我遇到了一個特殊問題。如何使用可能的響應類型消耗Retrofit響應?

我使用的是翻新2.3.0,以及翻新gson轉換器2.3.0。

我的問題如下。 我正在使用的Web服務API將在請求200-OK時響應2個可能的響應模型。

  1. Web服務處理的請求罰款並響應預期響應模型中定義的響應回調。
  2. Web服務無法處理請求併發回異常模型作爲響應。仍然發送一個200-OK ...

相信我,我知道這裏的問題...如果Web服務異常被拋出,Web服務不應該成功響應......它應該與響應一個500-5xx。所有這些會變得更容易。無論如何,我需要遵守這個邏輯。

這就是我所擁有的,它正在工作,但我認爲有一個更好的方法來解決這個問題,而且我不想一次又一次地寫相同的代碼,每次執行轉換操作時都會消耗響應。但是,我不確定哪裏是正確的方法。

call.enqueue(new Callback<JsonObject>() { 

    @Override 
    public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { 
     //cast operation 
     Gson gson = new Gson(); 
     ServiceException exception = gson.fromJson(response.body(), ServiceException.class); 
     if(response.isSuccessful()){ 
      if(null != exception.getCode()){ 
       //handleException(exception); 
      }else{ 
       //User authenticated successfully. 

       //cast operation 
       LoginResponseModel loginResponseModel = gson.fromJson(response.body(), LoginResponseModel.class); 
       //Perform actions with login response model. 

       //Launch dashboard if everything is ok. 
       Intent startDashboard = new Intent(LoginActivity.this, DashboardActivity.class); 
       startActivity(startDashboard); 
      } 
     } 
    } 

    @Override 
    public void onFailure(Call<JsonObject> call, Throwable t) { 
     Log.e(TAG, t.getMessage()); 
    } 

}); 

這是我理想的目標:

call.enqueue(new Callback<LoginResponseModel, ServiceException>() { 

     @Override 
     public void onResponse(Call<LoginResponseModel, ServiceException> call, Response<LoginResponseModel, ServiceException> response) { 
       if(response instanceof ServiceException){ 
        handleException(response); 
       }else if(response instanceof LoginResponseModel){ 
        //User authenticated successfully. 
        LoginResponseModel loginResponseModel = gson.fromJson(response.body(), LoginResponseModel.class); 
        //Perform actions with login response model. 

        //Launch dashboard if everything is ok. 
        Intent startDashboard = new Intent(LoginActivity.this, DashboardActivity.class); 
        startActivity(startDashboard); 

       } 
      } 
     } 

     @Override 
     public void onFailure(Call<LoginResponseModel, ServiceException> call, Throwable t) { 
      Log.e(TAG, t.getMessage()); 
     } 

    }); 

我需要一個自定義的回調實現,以實現我的目標? 我是否需要自定義響應攔截器? 我需要一個自定義響應轉換器嗎? 更好的方法的任何想法?

我對改造有點新,我還沒有找到關於這種情況的很多信息。

回答

0

嗯那麼使用try catch並處理gson JsonSyntaxException?類似這樣的:

call.enqueue(new Callback<JsonObject>() { 
     @Override 
     public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { 
      Gson gson = new Gson(); 
      try { 
       ServiceException exception = gson.fromJson(response.body(), ServiceException.class); 
       //handleException(exception); 
      } catch (JsonSyntaxException e) { 
       // Incorrect class, deserialize using LoginResponseModel 
       LoginResponseModel loginResponseModel = gson.fromJson(response.body(), LoginResponseModel.class); 
       //User authenticated successfully. 
       //Launch dashboard if everything is ok. 
       Intent startDashboard = new Intent(LoginActivity.this, DashboardActivity.class); 
       startActivity(startDashboard); 
      } 
     } 

     @Override 
     public void onFailure(Call<JsonObject> call, Throwable t) { 
      Log.e(TAG, t.getMessage()); 
     } 
    }); 
+0

此解決方案仍在每個響應處理程序上進行投射。不是我想要的行爲。我在我的問題中提到,我不希望在響應處理程序中執行此投射操作。 – TerNovi

+0

我明白了。也許解決方案是使用泛型類型。檢查此gson [doc](https://github.com/google/gson/blob/master/UserGuide.md#serializing-and-deserializing-generic-types) –

相關問題