2014-09-25 140 views
8

我正在使用的REST Api具有根据状态从服务器发送的自定义代码和消息,我想实现一个自定义Callback<T>,只有在状态代码为自定义错误处理与改造

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

失败响应的实施例::

从服务器接收到0

实施例成功响应

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

codemessage被所有请求返回时,data包含实际的响应值,所以我想做到以下几点:

  1. 检查代码消息和来电success()如果代码为0.
  2. 请致电failure()如果请求失败或code!= 0
  3. 建设基础上,数据响应自定义对象,并通过success()

什么是做到这一点的最佳方式传递呢?我到处搜索,找不到一个好的解决方案。我唯一得到的是让所有自定义对象也有codemessage字段,并检查它们的值在success()内,但这可能会导致未来出现问题,以免在继续之前忘记检查code

+0

其实改造提供了方法来构建自己的自定义错误处理程序! – Pavlos 2014-09-25 16:44:31

+0

你能给我一些指点或在哪里看样本? – Nima 2014-09-25 16:45:14

+0

http://square.github.io/retrofit/ “CUSTOM ERROR HANDLING” – Pavlos 2014-09-25 16:45:46

回答

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转换为REST的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的设计方法。如果您正在向服务器发送登录请求,则可以将此请求理解为创建资源的请求(例如经过身份验证的用户会话)。如果不发送正确的参数(在这种特殊情况下正确的用户名和密码),服务器应该拒绝的资源创建请求并返回一个4一百东西(4XX)HTTP状态代码,表明你的要求是不正确不知何故。改造会理解这个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 2017-01-06 09:15:29

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); 

祝你好运。