当前位置: 首页 > 知识库问答 >
问题:

从OKHttp拦截器返回错误(使用改型)

陶星波
2023-03-14
@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???
    }
}

共有1个答案

慎峻
2023-03-14

这篇文章帮助我实现了这个解决方案。感谢@mastov指明了正确的方向。

使用一个后端api,即使有错误也总是返回HTTP200。这是我对一个错误的响应示例

{"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;
    }
 类似资料:
  • 我以为这些最新版本应该是兼容的。有一条推文;https://twitter.com/JakeWharton/status/553066921675857922和Retrofit 1.9的更新日志也提到了它。 然而,当我尝试这个: 还是不行。setClient方法抱怨不兼容的客户端对象; 我错过了什么?我还看到OkHttpClient没有实现客户端接口。 我现在使用这种方法;https://medi

  • D/OKHTTP:主机:www.appido.ir D/OKHTTP:Connection:Keep-Alive d/okhttp:accept-encoding:gzip 1048576------WebKitFormBoundaryJDHM3Si8Enjzaba内容-配置:表单-数据;name=“FlowCurrentChunkSize” 23016-----WebKitFormBoundar

  • 我尝试使用OkHttp 3.12.0中最近添加的一个特性:全操作超时。为此,我还依赖retrofit 2.5.0中新的类,它允许我检索方法注释。 尽管它在使用拦截器中的链方法时工作得很好: 这是因为在呼叫排队之前必须设置呼叫超时吗?(而拦截器在过程中触发得太晚了?),或者这是其他原因?

  • 我想拦截一个错误的JSON输入,并使用Dropwizard应用程序返回自定义错误消息。我遵循了这里提到的定义自定义异常映射器的方法:http://gary-rowe.com/agilestack/2012/10/23/how-to-implement-a-runtimeexceptionmapper-for-dropwizard/。但它不适合我。同样的问题也被问到这里https://groups.

  • 当运行一个改型应用程序时,我得到以下错误: E/AndroidRuntime:致命异常:OkHttp Dispatcher进程:fr.univ_lehavre.greah.naoderapp,PID:20894java.lang.NosuchMethoderror:lokhttp3/internal/platform类中没有虚方法日志(ljava/lang/string;)V;或其超级类('OKH

  • 1. 前言 拦截器这个名词定义的非常形象,就像导弹要攻击目标的时候,可能会被先进的反导系统拦截,此处的反导系统就是一种拦截器。 我们开发的应用,对外暴露的是控制器中定义的 API 方法,我们可以在 API 方法的外围放置拦截器,所有对 API 的访问都可以通过拦截器进行过滤。 OK,那么这样的拦截有什么意义吗,其实已经很明显了,反导系统可以保护目标的安全并识别对目标的攻击行为。同理,拦截器可以跟踪