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

基于HTTP响应重试

养俊驰
2023-03-14

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

如果回答是:

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

202:返回成功

429:请等待2分钟,然后重试

5XX:等待5分钟,然后重试

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

共有2个答案

勾向文
2023-03-14

给RetroFit2一个尝试。

根据这个答案,您可以捕获HTTP响应代码并执行如下自定义逻辑:

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

我知道这个问题已经问了两年了,但也许这个解决方案对某人有所帮助。这个解决方案对我有效

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获得我们应该得到的时间。getHeaderFieldDint(“在”、-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();
        }
    }
 类似资料:
  • 我想处理的情况下401,403,500等只是状态代码应该返回而不是视图。

  • 我正在制作一个clojure web应用程序,它使用分块HTTP响应将数据流传输到客户端。当我使用在本地运行它时,它工作得很好,但是当我将它部署到Heroku时,它不能正常工作。 在我的github上可以找到一个显示这种行为的最小示例。前端(在中)执行AJAX GET请求,并在响应块到达时打印响应块。服务器使用http工具包每秒向连接的客户端发送一个新块。根据设计,HTTP请求永远不会完成。 当向

  • 我一直在学习spring Webflux和reactive programming,并陷入了一个问题,我试图解决的重试逻辑使用spring WebClient。我已经创建了一个客户机,并成功地调用了一个外部Web服务GETendpoint,该endpoint返回一些JSON数据。 当外部服务以状态响应时,响应包括标头,该标头具有一个值,指示在重试请求之前应等待多长时间。我想在spring WebF

  • 主要内容:HTTP响应完整格式HTTP响应完整格式 HTTP的响应也由三部分组成(响应行+响应头+响应体): 以下是一个实际的HTTP响应示例: ①报文协议及版本; ②状态码及状态描述; ③响应报文头,也是由多个属性组成; ④响应报文体,即我们真正要的“干货”。

  • 基本响应 当然,所有的路由及控制器必须返回某个类型的响应,并发送回用户的浏览器。Laravel 提供了几种不同的方法来返回响应。最基本的响应就是从路由或控制器简单的返回一个字符串: $router->get('/', function () { return 'Hello World'; }); 指定的字符串会被框架自动转换成 HTTP 响应。 响应对象 但是,对于大多数路由和控制器行为

  • Blade 中操作响应的对象是 Response 发送文本 Response#text 用于发送一个状态码为 200 的文本响应 public void responseText(Response response){ response.text("Hello World"); } 发送HTML Response#html 用于发送一个状态码为 200 的HTML响应 public voi