重试http连接

时间:2010-10-14 02:55:21

标签: java android

我正在发出http请求。我在一个平台(android)上,网络操作经常失败,因为网络连接可能不会立即可用。因此,我想在完全失败之前尝试相同的连接N次。想到这样的事情:

DefaultHttpClient mHttp = ...;

public HttpResponse runHttpRequest(HttpRequestBase httpRequest) 
    throws IOException
{
    IOException last = null;
    for (int attempt = 0; attempt < 3; attempt++) {
        try {
            HttpResponse response = mHttpClient.execute(httpRequest);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                return response;
            }
        } catch (IOException e) {
            httpRequest.abort();
            last = e;
        }
    }

    throw last;
}

我最担心的是某些状态下的连接在后续重试时无效。换句话说,我是否需要完全重新创建'httpRequest',我应该避免在catch块中调用httpRequest.abort(),并且只在最终失败时调用它吗?

由于

3 个答案:

答案 0 :(得分:8)

文档没有提到会发生这样的事情,尽管你必须尝试一下。但更重要的是,您的代码应该考虑一些事情......

  1. 您应该公开重试次数,允许调用者指定此值。
  2. 您应该只在抛出异常时重试;你现在重试,除非你得到200.但是,例如,如果你得到404 ......这并不意味着你的请求失败,因为网络没有失败......相反,你做了一个成功的回合 - 访问服务器,但服务器根本没有所请求的资源...所以在这种情况下重试真的没有意义。
  3. 按原样,您可以抑制各种不同类型的异常。记录列表中发生的所有异常并返回包含响应的某种结果对象(除非所有尝试都失败,否则可能为null)以及所有异常列表。否则,您会从发生的异常集中抛出一些任意异常,这可能会使故障模糊不清。
  4. 现在你只需要一遍又一遍地使用相同的请求......如果有拥堵,你只需要添加它。如果您的IP地址被禁止进行太多活动,您可能会添加到那个...任何类型的重试逻辑应该具有退避行为,其中重试之间有一些等待时间并且该间隔随着每次失败。

答案 1 :(得分:6)

HttpRequestRetryHandler似乎在这里可能会有所帮助。

答案 2 :(得分:3)

我建议使用来自jcabi-aspects的AOP和Java注释(我是开发人员):

@RetryOnFailure(attempts = 3, delay = 5)
public String load(URL url) {
  return url.openConnection().getContent();
}