在Retrofit android中处理错误响应

时间:2014-09-10 15:48:17

标签: android retrofit

我使用Retrofit作为我的网络库。一切都很顺利。 我只是有一个新要求,服务器在Json中发送响应,如果失败。 我想抓住整个响应,现在在故障回调中 RetrofitError ,没有在任何 RetrofitError 属性中给出我的服务器响应。

任何形式的帮助将不胜感激。感谢。

1 个答案:

答案 0 :(得分:1)

我想你想要得到的是在失败期间从你的api返回的json响应中的字段。我认为失败的过程与成功的过程非常相似。首先,您的响应对象需要有一个字段映射到json错误字段,或者您要从响应中提取的任何字段(成功或失败)。在成功的情况下,您可以直接获得转换后的响应,但是如果发生故障,您需要在返回的RetofitError对象上调用getResponse()以获取转换后的响应,然后提取返回的数据。

这是一个例子。

我有一个rails后端,成功时会响应一个令牌,如果不成功则会返回错误列表。这是rails控制器方法,如果这有帮助,但底线是有一个json条目错误,我想检查创建失败。

  def create
    @user = User.new(user_params)
    if @user.save
      sign_in_api(@user)
      render json: { token: @issued_remember_token }, status: 201
    else
      render json: { errors: @user.errors.full_messages }  , status: 406
    end
  end

这是我的改装电话

    @POST(API_URL + "/signup")
    void signup(@Body UserRequestParams requestParams,
            Callback<SignupResponse> tokenParms);

这是我的SignupResponse对象

public class SignupResponse extends BaseResponse {
    private String token;

    public String getToken() {
        return token;
    }

}

public class BaseResponse {
    private List<String> errors = new ArrayList<String>();
    private Boolean mSuccessful = false;
    public Response getRawResponse() {
        return rawResponse;
    }

    public void setRawResponse(Response rawResponse) {
        this.rawResponse = rawResponse;
    }

    private Response rawResponse;


    public BaseResponse() {
        super();
    }

    public List<String> getErrors() {
        return errors;
    }

    public void setSuccessful(Boolean successful) {
        mSuccessful = successful;
    }

    public Boolean isSuccessful() {
        return mSuccessful;
    }
}

结果是,改造将填充错误字段作为回调过程的一部分,就像它成功一样。现在我可以检查响应是否成功,并在响应对象上调用适当的方法。如果成功,则错误将为null,如果不成功,则为有效。

为了完整性,这里是我的例子中涉及的其他两个方法/类。

    @Subscribe
    public void onSignup(SignupRequest event) {
        System.out.println("inside api repo - making signup request");
        mRailsApi.signup(event, new RailsApiCallback<SignupResponse>(mBus, new SignupResponse()));
    }


public class RailsApiCallback<T extends BaseResponse> implements Callback<T> {

    private Bus mBus;
    private T mResponse;

    public RailsApiCallback(Bus bus, T response) {
        super();
        mBus = bus;
        mResponse = response;     
    }

    @Override 
    public void failure(RetrofitError retrofitError) {
        System.out.println(retrofitError.toString());
        T response = retrofitError != null && retrofitError.getBody() != null ? (T) retrofitError.getBody() : mResponse  ;
        response.setRawResponse(retrofitError.getResponse());
        response.setSuccessful(false);
        System.out.println("posting response to bus");
        mBus.post(response);
    }

    @Override
    public void success(T convertedResponse, Response rawResponse) {
        System.out.println(rawResponse.getBody());
        T response = convertedResponse != null ? convertedResponse : mResponse ;
        response.setSuccessful(true);
        response.setRawResponse(rawResponse);
        mBus.post(response);

    }
}