2016-02-23 14 views
13

Ho un webservice che restituisce un elenco di oggetti MyPOJO serializzati:Come possiamo gestire diversi tipi di risposta con Retrofit 2?

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

sia un oggetto di errore:

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

Utilizzando retrofit2, come posso recuperare l'errore?

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 
    }  
    } 
} 

Ecco eccezione GSON:

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

esempio retrofit viene creata usando GsonConverterFactory

+0

già chiesto http://stackoverflow.com/questions/24279245/how-to-handle-dynamic-json-in-retrofit – Rohit5k2

risposta

10

Ho avuto un problema simile e ho risolto utilizzando un generico Object e poi prova che tipo di risposta ho avuto usando 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 
    } 
}); 

In nel mio caso ho restituito MyPOJO o MyError e potevo essere sicuro che sarebbe stato uno di questi.

In altri casi, il backend ha restituito lo stesso oggetto di risposta, indipendentemente dal fatto che la richiesta abbia avuto esito positivo o meno.
Quindi all'interno di questo oggetto risposta ho avuto i miei dati effettivi all'interno di un campo "Oggetto". Quindi posso usare l'istanza di per determinare quale tipo di dati ho avuto. In questo caso ho sempre restituito lo stesso oggetto, indipendentemente dalla chiamata.

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

soluzione Ben scritto – Gabriel

Problemi correlati