【发布时间】:2020-06-10 21:34:17
【问题描述】:
我想在java中实现API的HTTP响应重试框架。
如果响应是:
400 : 将json中的参数设为null,然后重试
202 : 返回成功
429 : 等待 2 分钟再试一次
5XX : 等待 5 分钟再试一次
如果重试次数超过则抛出异常。是否有任何可用的库支持重试响应类型并允许编辑请求对象?如果没有,我该如何设计?周围有教程吗?
【问题讨论】:
标签: java-7
我想在java中实现API的HTTP响应重试框架。
如果响应是:
400 : 将json中的参数设为null,然后重试
202 : 返回成功
429 : 等待 2 分钟再试一次
5XX : 等待 5 分钟再试一次
如果重试次数超过则抛出异常。是否有任何可用的库支持重试响应类型并允许编辑请求对象?如果没有,我该如何设计?周围有教程吗?
【问题讨论】:
标签: java-7
我知道这个问题已经 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();
}
}
【讨论】:
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
}
}
【讨论】: