基于HTTP响应重试

时间:2017-12-28 17:09:16

标签: java-7

我想在java中对API的HTTP响应实现重试框架。

如果回复是:

400:在json中使参数为null,然后重试

202:回归成功

429:等待2分钟再试一次

5XX:等待5分钟再试一次

如果重试次数超过则抛出异常。是否有可用的库支持在响应类型上重试,还允许编辑请求对象?如果没有,我怎么设计一个?周围有没有教程?

2 个答案:

答案 0 :(得分:1)

我知道这个问题已经两年了,但是也许这个解决方案可以帮助某个人。该解决方案对我有用

public static void main(String[] args) {
        try {
            long start = System.currentTimeMillis();
            int retry = 0;
            boolean delay = false;
            int status = 0;
            do {
                if (delay) {
                    Thread.sleep(2000);
                }
                String url = "http://httpstat.us/429";
                URL u;
                u = new URL(url);
                HttpURLConnection con = (HttpURLConnection) u.openConnection();
                int random = (int) Math.random() * 10000;
                con.setRequestProperty("User-Agent", "skym/1.0.8 /" + random);
                con.setRequestProperty("Accept", "application/json");
                con.setRequestMethod("GET");
                con.setDoOutput(false);
                con.setDoInput(true);
                con.setUseCaches(false);
                con.setAllowUserInteraction(false);
                con.setConnectTimeout(30000);
                con.setReadTimeout(30000);
                con.setRequestProperty("Content-Type", "application/xml");
                status = con.getResponseCode();
                con.disconnect();
                System.out.println(status);
                System.out.println("Done in " + (System.currentTimeMillis() - start));
                retry++;
                delay = true;
            } while (retry < 5 && status == 429);

        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

我们可以修改此代码,而不是等待2分钟,因为某些API需要5分钟或超过5分钟,因此我们需要通过con.getHeaderFieldInt(“ Retry-After”,-1);

>

所以修改后的代码将是

public static void main(String[] args) {
        try {
            long start = System.currentTimeMillis();
            int retry = 0;
            boolean delay = false;
            int MIN_RETRY_AFTER = 2;
            int MAX_RETRY_AFTER = 10;
            int status = 0;
            int retryAfter = 0;
            int random = 0;
            URL u;
            do {
                if (delay) {
                    Thread.sleep(1000 * retryAfter);
                }

                String url = "http://httpstat.us/429";

                u = new URL(url);
                HttpURLConnection con = (HttpURLConnection) u.openConnection();
                random = (int) Math.random() * 10000;
                con.setRequestProperty("User-Agent", "skym/1.0.8 /" + random);
                con.setRequestProperty("Accept", "application/json");
                con.setRequestMethod("GET");
                con.setDoOutput(false);
                con.setDoInput(true);
                con.setUseCaches(false);
                con.setAllowUserInteraction(false);
                con.setConnectTimeout(30000);
                con.setReadTimeout(30000);
                con.setRequestProperty("Content-Type", "application/xml");
                status = con.getResponseCode();
//              to get the time you should wait before the next request
                retryAfter = con.getHeaderFieldInt("Retry-After", -1);
                if (retryAfter < 0) {
                    retryAfter = 0;
                }
                if (retryAfter < MIN_RETRY_AFTER) {
                    retryAfter = MIN_RETRY_AFTER;
                } else if (retryAfter > MAX_RETRY_AFTER) {
                    retryAfter = MAX_RETRY_AFTER;
                }
                con.disconnect();
                System.out.println(status);
                System.out.println(retryAfter);
                System.out.println("Done in " + (System.currentTimeMillis() - start));
                retry++;
                delay = true;
            } while (retry < 5 && status == 429);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

答案 1 :(得分:0)

Give Retrofit2 a try.

As per this answer,您可以捕获HTTP响应代码并执行自定义逻辑,如下所示:

@Override
public void onResponse(Call<YourModel> call, Response<YourModel> response) {
    if (response.code() == 200) {
       // Do awesome stuff
    } else {
       // Handle other response codes
    }
}