2016-02-23 10 views
13

私はシリアル化さMyPOJOオブジェクトのリストのいずれかを返すWebサービスがあります。Retrofit 2を使用して異なるレスポンスタイプを処理するにはどうすればよいですか?

[ 
    { //JSON MyPOJO }, 
    { //JSON MyPOJO } 
] 

は、エラーオブジェクトのいずれか:retrofit2を使用して

{ 
    'error': 'foo', 
    'message':'bar' 
} 

を、どのように私はエラーを取得することができますか?ここで

Call<List<MyPOJO>> request = ... 
request.enqueue(new Callback<List<MyPOJO>>() { 
    @Override 
    public void onResponse(Response<List<MyPOJO>> response) { 
     if (response.isSuccess()) { 
      List<MyPOJO> myList = response.body(); 
      // do something with the list... 
     } else { 
      // server responded with an error, here is how we are supposed to retrieve it 
      ErrorResponse error = ErrorResponse.fromResponseBody(apiService.getRetrofitInstance(), response.errorBody()); 
      processError(error); 
      // but we never get there because GSON deserialization throws an error ! 
     } 
    } 

    @Override 
    public void onFailure(Throwable t) { 
    if(t instanceof IOException){ 
     // network error 
    }else if(t instanceof IllegalStateException){ 
     // on server sending an error object we get there 
     // how can I retrieve the error object ? 
    }else { 
     // default error handling 
    }  
    } 
} 

はGSON例外です:

java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ 

改修インスタンスがGsonConverterFactory

+0

はすでにhttp://stackoverflow.com/questions/24279245/how-to-handle-dynamic-json-in-retrofit – Rohit5k2

答えて

10

を使用して作成され、私は同様の問題があったと私は一般的なObjectを使用して、どのようなタイプのをテストすることによって、それを解決しました私はinstanceofを使用していた応答

Call<Object> call = api.login(username, password); 
call.enqueue(new Callback<Object>() 
{ 
    @Override 
    public void onResponse(Response<Object> response, Retrofit retrofit) 
    { 
     if (response.body() instanceof MyPOJO) 
     { 
      MyPOJO myObj = (MyPOJO) response.body(); 
      //handle MyPOJO 
     } 
     else //must be error object 
     { 
      MyError myError = (MyError) response.body(); 
      //handle error object 
     } 
    } 

    @Override 
    public void onFailure(Throwable t) 
    { 
    ///Handle failure 
    } 
}); 

私の場合MyPOJOまたはMyErrorのいずれかが返されていて、それがこれらのいずれかになると確信することができました。

他のケースでは、リクエストが成功したかどうかに関係なく、バックエンドは同じレスポンスオブジェクトを返していました。
このレスポンスオブジェクトの中で、私は "Object"フィールド内に自分の実際のデータを持っていました。それから私は、私が持っていたデータの種類を判断するためにインスタンスを使用することができます。この場合、呼び出しが何であっても、常に同じオブジェクトが返されました。

public class MyResponse { 

    private int responseCode; 
    private String command; 
    private int errorno; 
    private String errorMessage; 
    private Object responseObject; //This object varies depending on what command was called 
    private Date responseTime; 
} 
3
Call<LoginResponse> call = apiService.getUserLogin(usernametext, passwordtext); 
    call.enqueue(new Callback<LoginResponse>() { 
     @Override 
     public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) { 
      Log.e("responsedata","dd"+response.toString()); 
      if (response.code()==200) { 
       showMessage(response.body().getMessage()); 
       Intent intent = new Intent(LoginActivity.this, MainAct.class); 
       startActivity(intent); 
      } 
      else 
       try { 
        LoginError loginError= gson.fromJson(response.errorBody().string(),LoginError.class); 
        showMessage(loginError.getMessage()); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
     } 

     @Override 
     public void onFailure(Call<LoginResponse> call, Throwable t) { 

     } 
    }); 
} 
+1

よく書かれたソリューションを求めて – Gabriel

関連する問題