如何处理 Retrofit 2.0 中的错误
Posted
技术标签:
【中文标题】如何处理 Retrofit 2.0 中的错误【英文标题】:How to handle error in Retrofit 2.0 【发布时间】:2016-11-13 05:53:39 【问题描述】:我想处理 Retrofit 2.0 中的错误
得到例如code=404
和 body=null
,但 errorBody()
包含 ErrorModel
中的数据(Boolean status
和 String info
)。
这是errorBody().content
:[text=\n"status":false,"info":"Provided email doesn't exist."]
。
我怎样才能得到这些数据?
谢谢你帮助我!
这是我的改造请求代码:
ResetPasswordApi.Factory.getInstance().resetPassword(loginEditText.getText().toString())
.enqueue(new Callback<StatusInfoModel>()
@Override
public void onResponse(Call<StatusInfoModel> call, Response<StatusInfoModel> response)
if (response.isSuccessful())
showToast(getApplicationContext(), getString(R.string.new_password_sent));
else
showToast(getApplicationContext(), getString(R.string.email_not_exist));
@Override
public void onFailure(Call<StatusInfoModel> call, Throwable t)
showToast(getApplicationContext(), "Something went wrong...");
);
【问题讨论】:
你能放一些代码吗 你的意思是这段代码? 【参考方案1】:如果您想在错误响应出现时获取数据(通常是除了 200 之外的响应代码),您可以在 onResponse()
方法中这样做:
if (response.code() == 404)
Gson gson = new GsonBuilder().create();
YourErrorPojo pojo = new YourErrorPojo();
try
pojo = gson.fromJson(response.errorBody().string(), YourErrorPojo.class);
Toast.makeText(context, pojo.getInfo(), Toast.LENGTH_LONG).show();
catch (IOException e)
// handle failure at error parse
生成YourErrorPojo.class
时,请执行以下步骤:
转到Json Schema 2 Pojo
粘贴您的示例Json
,并选择源类型Json,注释Gson
您的示例Json
是:"status":false,"info":"Provided email doesn't exist."
点击Preview,它会为你生成Pojo
类。
将此添加到您的build.gradle
:compile 'com.google.code.gson:gson:2.7'
我在这个解决方案中使用了Gson
,但你可以使用response.errorBody().string()
获取你的Json
字符串:response.errorBody().string()
【讨论】:
我试过这个代码:Gson gson = new GsonBuilder().create();
StatusInfoModel error = new StatusInfoModel();
try error = gson.fromJson(response.errorBody().string(), StatusInfoModel.class);
showToast(getApplicationContext(), error.getInfo());
catch (IOException e) // handle failure to read error
,但是有一个错误:Class must either be declared abstract or implement abstract method
。
@y07k2 你能提供截图我去看看吗?
s32.postimg.org/eww0vfotx/error.png。当我删除else
语句错误消失。
@y07k2 啊,我看到了你的错误,因为我错过了一个 "" ,我将它添加到我的答案中。请查看已编辑的答案。
完美运行!谢谢! :)知道如何简化它(我的意思是放入方法并在不同的地方调用它)?【参考方案2】:
Retrofit 不会将 404 视为失败,因此会进入 onSuccess。
response.isSuccessful()
如果响应码在200-300的范围内为真,则在此处输入else。
if (response.isSuccessful())
showToast(getApplicationContext(), getString(R.string.new_password_sent));
else
// A 404 will go here
showToast(getApplicationContext(), getString(R.string.email_not_exist));
但是,由于您的响应不成功,因此您不会获得带有.body()
的响应正文,而是带有errorBody()
,当请求成功时将填充errorBody,但response.isSuccessful()
返回false(因此在不是 200-300 的状态码)。
【讨论】:
是的,我知道可以这样完成,但我不想每次都输入String errorMsg
,当我可以(至少我相信我可以)从errorBody()
得到的时候.
errorBody
用于发生错误时,不适用于404的情况。404被视为成功
这很奇怪。为什么我在errorBody()
中收到这些数据,而不是在body()
中?
我的错。 errorBody
包含响应不成功时的响应。所以万一没有错误,但状态码不是200-300。如您所说,状态码 404 将在 errorBody 中得到响应
"response.isSuccessful() 如果响应代码在 200-300 范围内,则为 true" 准确地说:以 2XX 开头的 http 响应是成功,3XX 重定向,4XX 客户端错误和5XX 服务器端错误。【参考方案3】:
我正在使用这个库Retrobomb,您不必在该级别进行序列化。 它易于使用和定制。它支持每个错误类型或错误代码的注释。 如果您愿意,您可以解开所有错误并自行处理。
@ErrorMapping(code = 401, errorType = Unauthorized.class)
@PATCH("/v1/widgets/id")
Single<Widget> updateWidget(@Path("id") String id, @Body Widget widget);
【讨论】:
【参考方案4】:如果您想在错误响应出现时获取数据(通常是响应代码,除了 200),您可以在 onResponse()
方法中这样做:
override fun onResponse(call: Call<LoginData>?, response: Response<LoginData>?)
if (response != null)
if (response.code() == 200 && response.body() != null)
val loginData = response.body()
if (loginData != null)
//Handle success case...
else if (response.code() == 401)
val converter = ApiClient.getClient()?.responseBodyConverter<ErrorResponseData>(
ErrorResponseData::class.java,
arrayOfNulls<Annotation>(0))
var errorResponse: ErrorResponseData? = null
errorResponse = converter?.convert(response.errorBody())
if (errorResponse != null)
//Handle Error case..
【讨论】:
【参考方案5】:对于 Kotlin:
只需按照此代码将您的 errorBody 转换为您的响应:
if(response.isSuccessful)
val data = response.body()!!
else
val gson = GsonBuilder().create()
try
var pojo = gson.fromJson(
response.errorBody()!!.string(),
CommentResponse::class.java)
Log.e("ERROR_CHECK","here else is the error$pojo")
catch (e: IOException)
// handle failure at error parse
【讨论】:
以上是关于如何处理 Retrofit 2.0 中的错误的主要内容,如果未能解决你的问题,请参考以下文章