All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sinacloud.scs.retry.RetryHandler Maven / Gradle / Ivy

The newest version!
package com.sinacloud.scs.retry;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.NoRouteToHostException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.HashSet;

import javax.net.ssl.SSLHandshakeException;

import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;



/**
 * 网络连接重试的Handler
 * @author loopj
 * created by Nov 16, 2011 03:10:00 PM
 */

public class RetryHandler implements HttpRequestRetryHandler {
	
    private static final int RETRY_SLEEP_TIME_MILLIS = 500;						//retry时SystemClock睡1.5秒
    private static HashSet> exceptionWhitelist = new HashSet>();  //白名单异常集合,可重试
    private static HashSet> exceptionBlacklist = new HashSet>();  //黑名单异常集合,放弃重试

    static {
        // 无响应时重试
        exceptionWhitelist.add(NoHttpResponseException.class);
        // wifi转换到3G导致UnknownHostException异常时重试
        exceptionWhitelist.add(UnknownHostException.class);
        // wifi转换到3G导致SocketException异常时重试
        exceptionWhitelist.add(SocketException.class);

        // 如果线程被打断就不重试
        exceptionBlacklist.add(InterruptedIOException.class);
        // 握手失败不重试(常见为无证书)
        exceptionBlacklist.add(SSLHandshakeException.class);
        // 无法路由到主机不重试
        exceptionBlacklist.add(NoRouteToHostException.class);
    }

    private final int maxRetries; //最大重试次数

    public RetryHandler(int maxRetries) {
        this.maxRetries = maxRetries;
    }
    
    /**
     * 重试请求
     * exception为IO异常,executionCount为执行次数,context是HttpContext上下文
     * 返回布尔型的retry :retry为false时不重试 , retry为true时重试
     */
//    @Override
    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
        boolean retry;

        Boolean b = (Boolean) context.getAttribute(ExecutionContext.HTTP_REQ_SENT);
        boolean sent = (b != null && b.booleanValue());

        if(executionCount > maxRetries) {
            //如果执行次数大于最大连接数则不再重试
            retry = false;
        } else if (exceptionBlacklist.contains(exception.getClass())) {
            //黑名单集合里的异常不重试
            retry = false;
        } else if (exceptionWhitelist.contains(exception.getClass())) {
            //白名单集合里的立即重试
            retry = true;
        } else if (!sent) {
            // 大部分由于其他错误导致请求还没有被完全发送出去,则立即重试
            retry = true;
        } else {
            // 重发所有幕等的请求
            HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
            String requestType = currentReq.getMethod();
            if(!requestType.equals("POST")) {
            	//如果requestType不是POST,则立即重试
                retry = true;
            } else {
                //否则不重试
                retry = false;
            }
        }

        if(retry) {
        	//如果重试,SystemClock睡0.5秒
        	try {
				Thread.sleep(RETRY_SLEEP_TIME_MILLIS);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        } else {
            exception.printStackTrace();
        }

        return retry;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy