2017-06-16 64 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) –

相关问题