gpt4 book ai didi

java - 从 OKHttp 拦截器返回错误(使用改造)

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:40:35 25 4
gpt4 key购买 nike

我正在使用 OkHttp 和 Retrofit 来发出我的应用程序的网络请求。我还在使用拦截器进行身份验证,并在必要时重试请求。

服务器有时会出现临时问题,虽然响应状态为 200 OK,但返回空主体。这导致我的应用程序崩溃,因为调用了 Retrofit Callback 的成功 block ,返回的自定义对象(并使用 GSON 解析)为 null,并且成功回调中的代码假定返回了一个对象。

我已经向服务器团队报告了这个问题,但我也想修复它,而不必使用空检查将所有成功回调代码包装在整个应用程序中。

目前我倾向于两种选择,但欢迎任何其他想法:1) 不从拦截器返回(这可能吗?)并且只显示一个错误对话框2) 返回将使 Retrofit 调用回调的失败部分的内容。

我的代码如下。如您所见,当收到空主体时,我最多重试请求 3 次。

@Override
public Response intercept(Chain chain) throws IOException
{
// First
Request request = chain.request();
Response response = chain.proceed(request);

....
....
....

// Retry empty body response requests for a maximum of 3 times
Integer retryMaxCount = 3;
MediaType contentType = response.body().contentType();
String bodyString = response.body().string();

while (bodyString.length() == 0 && retryMaxCount > 0)
{
//Empty body received!, Retrying...

retryMaxCount--;
response = chain.proceed(request);
bodyString = response.body().string();
}

if (bodyString.length() != 0)
{
// Create and return new response because it was consumed
ResponseBody newResponseBody = ResponseBody.create(contentType, bodyString);
return response.newBuilder().body(newResponseBody).build();
}
else
{
// WHAT TO WRITE HERE???
}
}

非常感谢。

最佳答案

刚遇到相同的情况,这篇文章帮助我实现了解决方案。感谢@mastov 指出了正确的方向。

使用始终返回 HTTP 200 的后端 api,即使出现错误也是如此。这是我的错误响应示例

{"status":403,"message":"Bad User credentials","time":1495597740061,"version":"1.0"}

这里有一个简单的实现来补充这个答案。

public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
ResponseBody body = response.body();
// Only intercept JSON type responses and ignore the rest.
if (body != null && body.contentType() != null && body.contentType().subtype() != null && body.contentType().subtype().toLowerCase().equals("json")) {
String errorMessage = "";
int errorCode = 200; // Assume default OK
try {
BufferedSource source = body.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
Charset charset = body.contentType().charset(Charset.forName("UTF-8"));
// Clone the existing buffer is they can only read once so we still want to pass the original one to the chain.
String json = buffer.clone().readString(charset);
JsonElement obj = new JsonParser().parse(json);
// Capture error code an message.
if (obj instanceof JsonObject && ((JsonObject) obj).has("status")) {
errorCode = ((JsonObject) obj).get("status").getAsInt();
}
if (obj instanceof JsonObject && ((JsonObject) obj).has("message")) {
errorMessage= ((JsonObject) obj).get("message").getAsString();
}
} catch (Exception e) {
Log.e(TAG, "Error: " + e.getMessage());
}
// Check if status has an error code then throw and exception so retrofit can trigger the onFailure callback method.
// Anything above 400 is treated as a server error.
if(errorCode > 399){
throw new Exception("Server error code: " + errorCode + " with error message: " + errorMessage);
}
}

return response;
}

关于java - 从 OKHttp 拦截器返回错误(使用改造),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32669623/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com