2014-09-25 3 views
8

REST Api Я работаю с пользовательскими кодами и сообщениями, которые отправляются с сервера в зависимости от состояния, я хотел бы реализовать пользовательский Callback<T>, который вызывает метод success, только если код состояния был 0.Пользовательская обработка ошибок с помощью дооснащения

Пример УСПЕХ Ответ получен с сервера:

{ 
    "code":"0", 
    "message":"success", 
    "data": { 
    "actual_data":"goes_here", 
    "need_to_construct_objects","from_data" 
    } 
} 

Пример FAILURE Response:

{ 
    "code":"301", 
    "message":"wrong_password", 
    "data": { 
    "actual_data":"will_be_null", 
    "no_need_to_construct_objects","from_data" 
    } 
} 

code и message возвращаются все запросы, то data содержит фактические значения отклика, так что я хотел бы сделать следующее:

  1. Проверьте сообщение на код и и вызывать только success() если код равен 0.
  2. Звоните failure() если запрос не выполнен или код! = 0
  3. Построить пользовательские объекты, основанные на данных ответа и передать их через success()

Что такое лучший способ сделать это? Я искал везде и не мог найти хорошего решения. Единственное, что я получил, это позволить всем пользовательским объектам иметь поля code и message и проверить их значения внутри success(), но это может привести к проблемам в будущем, если кто-то забудет проверить code перед продолжением.

+0

На самом деле Retrofit предоставляет возможность создания собственного обработчика ошибок! – Pavlos

+0

Не могли бы вы дать мне несколько указателей или где искать образец? – Nima

+0

http://square.github.io/retrofit/ «ОБРАБОТКА ТАМОЖЕННОЙ ОШИБКИ» – Pavlos

ответ

0

Это, по крайней мере, поможет вам начать работу. Вы можете в принципе создать свой собственный обратный вызов, а затем справиться с успехом. Посмотрите, что было отправлено и что вам нужно.

public class CustomCallback implements Callback { 
    @Override 
     public void success(Object o, Response response) { 

       //Check for success 
       //if(Success) 
       //callback.success(o, response); 
       //else 
       //Check for error 
       //callback.failure(error); 


     } 
    } 
3

Вы можете сделать это быстро, просто создав абстрактный класс, который реализует обратный вызов и объявит ваши собственные методы абстрактного успеха и отказа. Абстрактный класс будет обрабатывать стандартные методы обратного вызова Retrofit, интерпретировать ответ и соответствующим образом называть абстрактные методы.

Я думаю, что еще один возможный подход к этому - переопределить интерфейс клиента Retrofit для создания собственного объекта Response.

Если продлить OkClient, он может идти, как это:

public class CustomClient extends OkClient { 

    @Override public Response execute(Request request) throws IOException { 
      Response originalRespone = super.execute(request); 

      int statusCode = 0; 
      //TODO: read JSON response here (using GSON or similar, and extract status code and message... etc.) 

      //Convert the status code to HTTP standard status codes, according to the documentation you have. 
      if(statusCode == 0) statusCode = 200; 
      //Reconstruct a Response object 
      return new Response(originalResponse.getUrl(), statusCode, originalResponse.getReason() /*should probably replace with parsed message*/, originalResponse.getHeaders(), originalResponse.getBody()); 
    } 

Это может быть больше работы, чем обработки Вашего дела в обратный вызов, но я думаю, что это может помочь, если в какой-то момент API переходит в RESTful API конвенций.

Это решение имеет свою проблему, хотя это означает, что преобразование JSON будет работать дважды. Один в вашем клиенте, а другой - с помощью Retrofit. Не уверен, как правильно это сделать в данный момент. Возможно, что-то вокруг TypedInput и фиктивный конвертер, который передает уже преобразованные объекты.

0

В вашем случае, вы можете иметь класс, который отображает ваш ответ JSON:

class CustomResponse { 
    String code; 
    String message; 
    Data data; 

    static class Data { 
    String actualData; 
    String needToContructObjects; 
    String noNeedToContructObjects; 
    } 
} 

Тогда, так как вы вернулись к Java объекты мира, вы можете иметь заводскую как объект внутри вашего успеха обратный вызов метода, который создает желаемый объект на основе возвращенного пользовательского ответа. Если вы хотите получить этот ответ в обратном вызове отказа, я бы пересмотрел его с помощью Retrofit, так как ваш API не соответствует хорошему дизайну Rest.

Хотя это и возможно, и вы понимаете, что не можете участвовать в разработке API, имейте в виду, что это не очень хороший подход к API-дизайну. Если вы отправляете запрос на вход на сервер, вы можете понять этот запрос как запрос на создание ресурса (например, сеанс аутентифицированного пользователя). Если вы не отправляете правильные параметры (правильное имя пользователя и пароль в этом конкретном случае), сервер должен отклонить запрос на создание ресурса и отправить обратно код состояния сотовой сети (4xx), указывающий, что ваш запрос неверен как-то. Модернизация будет понимать этот код состояния 4xx и вызывать обратный вызов отказа, где вы могли бы соответствующим образом обработать ответ.

1

Создание пользовательских ResponseBodyConverter так:

public class CustomResponseBodyConverter<T> implements Converter<ResponseBody, T> { 
private final TypeAdapter<T> adapter; 

CustomResponseBodyConverter(TypeAdapter<T> adapter) { 
    this.adapter = adapter; 
} 

@Override 
public T convert(ResponseBody value) throws IOException,CustomException { 
    String json = ""; 
    try { 
     String body = value.string(); 
     json = new JSONObject(body).getJSONObject("data").toString(); 
     int code = new JSONObject(body).getInt("code"); 
     String message = new JSONObject(body).getString("message"); 
     if(code != 0){ 
      throw new CustomException(message); 
     } 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
    return adapter.fromJson(json); 
    } 
} 
+0

Как это использовать с помощью дооснащения – taotao

0

Это лучшая идея для реализации обратного вызова. Ниже вы можете привести пример.

public abstract class DefaultRequestCallback<T> implements Callback<T> { 

    public abstract void failure(Meta meta); 

    public abstract void success(T responseBean); 

    @Override 
    public void success(T baseResponseBean, Response response) { 
     // You can check your responsebean's error code and 
     // convert it to a default error 
     BaseResponseBean bean = (BaseResponseBean) baseResponseBean; 
     if (bean == null) { 
      failure(new Meta(ApplicationConstants.ERROR_RETROFIT, "Unknown Error!")); 
     } else if (bean.getMeta() != null && bean.getMeta().getCode() != ApplicationConstants.RESULT_SUCCESS) { 
      failure(bean.getMeta()); 
     } else { 
      success(baseResponseBean); 
     } 
    } 

    @Override 
    public void failure(RetrofitError error) { 
     // Convert default error to your custom error. 
     Meta meta = new Meta(ApplicationConstants.ERROR_RETROFIT, "Error Unknwon"); 
     failure(meta); 
    } 
} 

Дайте свой собственный обратный вызов вашему методу интерфейса переоснащения.

void yourMethod(DefaultRequestCallback<YourResponseBean> callback); 

Удачи.

Смежные вопросы