【问题标题】:Retry based on HTTP response基于 HTTP 响应重试
【发布时间】:2020-06-10 21:34:17
【问题描述】:

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

如果响应是:

400 : 将json中的参数设为null,然后重试

202 : 返回成功

429 : 等待 2 分钟再试一次

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

如果重试次数超过则抛出异常。是否有任何可用的库支持重试响应类型并允许编辑请求对象?如果没有,我该如何设计?周围有教程吗?

【问题讨论】:

标签: java-7


【解决方案1】:

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

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();
        }
    }

【讨论】:

    【解决方案2】:

    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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-03-04
      • 2019-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      • 1970-01-01
      相关资源
      最近更新 更多