2017-06-16 4 views
1

私は新しいプロジェクトの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()); 
     } 

    }); 

は、私は自分の目標を達成するために、カスタムコールバックの実装が必要ですか? カスタムレスポンスインターセプタが必要ですか? カスタム応答コンバータが必要ですか? より良いアプローチのアイデアですか?

私はRetrofitに少し新しく、このようなシナリオに関する多くの情報は見つかりませんでした。

答えて

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)を確認してください。 –

関連する問題