如何使用Retrofit处理错误?

时间:2017-01-08 23:53:22

标签: retrofit retrofit2

我的服务器为所有请求返回基本的JSON结构,如:

{  
    "success": false,
    "data": {  
        "errors": {  
            "email": [  
                "This is not an email."
            ],
            "password": [  
                "The password must be at least 6 characters."
            ]
        }
    }
}

success可以是真或假,数据可以返回许多内容,从errors到应用可能需要的数据。

如何使用Retrofit处理此响应(成功和错误)?

需要更改/添加到我的Retrofit API调用中的内容是什么?

Call<BasicResponse> call = apiService.login(emailString, passwordString);
call.enqueue(new Callback<BasicResponse>() {
    @Override
    public void onResponse(Call<BasicResponse> call, Response<BasicResponse> response) {
        //
    }

    @Override
    public void onFailure(Call<BasicResponse> call, Throwable t) {
        //
    }
});

2 个答案:

答案 0 :(得分:0)

基本上你会想要使用你的模型。这里有几个选项,但最后它归结为api的响应代码以及如何构建模型。

让我们首先让模型脱离困境。处理错误与否的对象的一种方法是将其作为模型的一个字段。假设您有错误对象:

public class Errors {
  // ...
}

这表示json中的errors对象:

"errors": {  
        "email": [  
            "This is not an email."
        ],
        "password": [  
            "The password must be at least 6 characters."
        ]
    }

现在假设您有一个数据对象来表示json对象:

"data": {  
    "errors": {  
        "email": [  
            "This is not an email."
        ],
        "password": [  
            "The password must be at least 6 characters."
        ]
    }
}

你可以简单地拥有:

public class Data {
   @SerializedName("success")
   @Expose
   private boolean success;
   @SerializedName("errors")
   @Expose
   private Errors errors;
   // Here you can then add other models, i.e:
   // @SerializedName("user")
   // @Expose
   // private User user;
 }

如您所见,您可以将其余模型添加到Data对象。如果响应成功,errors将为空,success为真。当响应不成功时,您将遇到相反的情况。您可以查看此answer以获取更多详细信息以及实现此目的的其他方法。

现在到处理错误响应的部分。

如果您的通话成功,您最终会进入onResponse来电。这意味着您必须先检查Data.success的值,然后才能开始与对象进行交互。如果false您知道可以访问errors字段而不生成NullPointerException,而true知道您已正确检索数据。

仅当示例套接字超时或序列化和反序列化请求时出现异常时,才会调用

onFailure

答案 1 :(得分:-1)

这就是您需要的Retrobomb,您可以创建一个带有列表错误的模型。

您可以从服务器返回422异常

@RetrobombMappings(
  ErrorMapping(code = 422, errorType =  ErrorMap::class)
)
@Headers("Content-Type: application/json")
@POST("/endpoint")
fun createFoo(@Body params: Map<String, String>): Completable


data class ErrorMap(@SerializedName("errors") val errors: ErrorMap.Error){

    class Error(@SerializedName("email") val email: List<String>?,
                @SerializedName("password") val password : List<String>?)

}

错误将很容易处理。