HttpClient異常重試

一、 HttpClient異常重試

       當請求發生異常時,經過異常處理機制自動從新請求。

二、前提:

      被請求的方法必須是冪等的:就是屢次請求服務端結果應該是準確且一致的。
      適合的方法:好比根據ID,修改人員姓名,不管請求屢次結果都是同樣,這就是冪等。
       不適合的方法:好比減小帳號50元,屢次請求將屢次扣減,

三、實現方式:

     想要實現異常重試,須要實現它提供的一個接口 HttpRequestRetryHandler,並實現retryRequest方法。
   而後set到HttpClient中。該httpClient就具有了重試機制

四、HttpClient提供了標準和默認兩個實現類

  4.1 StandardHttpRequestRetryHandler

    該類默認幾個方法爲冪等,如PUT,GET,HEAD等POST外的方法,若是自定義能夠參考他的實現方式,

  4.2  DefaultHttpRequestRetryHandler

          略

五、demo

    本文爲了演示重試機制,自定義了一個本文經過自定義一個實現類,爲了讓你們看到重試的效果,將不識別的主機異常,讓它重試,代碼以下, java

    在實現的 retryRequest方法中,遇到不識別主機異常,返回true,請求將重試。最多重試請求5次

package httpcomponents;

import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.impl.client.*;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;

/**
* Created by shuangjun.yang on 2016/4/1.
*/
public class HttpRetryCustomTest {
    public static void main(String[] args){
        HttpRequestRetryHandler httpRequestRetryHandle = new StandardHttpRequestRetryHandler(1,false);
        HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                if (executionCount >= 5) {
                    // Do not retry if over max retry count
                    return false;
                }
                if (exception instanceof InterruptedIOException) {
                    // Timeout
                    return false;
                }
                if (exception instanceof UnknownHostException) {
                    // Unknown host  修改代碼讓不識別主機時重試,實際業務當不識別的時候不該該重試,再次爲了演示重試過程,執行會顯示5次下面的輸出
                    System.out.println("不識別主機重試");  
                    return true;
                }
                if (exception instanceof ConnectTimeoutException) {
                    // Connection refused
                    return false;
                }
                if (exception instanceof SSLException) {
                    // SSL handshake exception
                    return false;
                }
                HttpClientContext clientContext = HttpClientContext.adapt(context);
                HttpRequest request = clientContext.getRequest();
                boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                if (idempotent) {
                    // Retry if the request is considered idempotent
                    return true;
                }
                return false;
            }
        };
       
        CloseableHttpClient httpClient = HttpClients.custom()
                .setRetryHandler(httpRequestRetryHandler)
                .build();
        HttpGet httpGet = new HttpGet("http://www.begincodee.net");  //不存在的域名
        try {
            HttpResponse response =  httpClient.execute(httpGet, HttpClientContext.create());
            HttpEntity entity = response.getEntity();
            System.out.println(EntityUtils.toString(entity));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
相關文章
相關標籤/搜索