HttpMethodDirector源码解析

变量

//方法连接器
private ConnectMethod connectMethod;
//HTTP状态
private HttpState state;
//主机配置
private HostConfiguration hostConfiguration;
//HTTP连接管理器
private HttpConnectionManager connectionManager;
//HTTP客户端参数
private HttpClientParams params;
//HTTP连接
private HttpConnection conn;
//是否释放连接
private boolean releaseConnection = false;
//授权挑战处理器
private AuthChallengeProcessor authProcessor = null;
//重定向位置
private Set redirectLocations = null;

 

构造方法

public HttpMethodDirector(HttpConnectionManager connectionManager, HostConfiguration hostConfiguration, HttpClientParams params, HttpState state) {
    this.connectionManager = connectionManager;
    this.hostConfiguration = hostConfiguration;
    this.params = params;
    this.state = state;
    this.authProcessor = new AuthChallengeProcessor(this.params);
}

 

主要执行方法execute

具体解析可看代码中的注释:

public void executeMethod(HttpMethod method) throws IOException, HttpException {
    if(method == null) {
        throw new IllegalArgumentException("Method may not be null");
    } else {
        this.hostConfiguration.getParams().setDefaults(this.params);
        method.getParams().setDefaults(this.hostConfiguration.getParams());
        //获取传入的缺省标题,这个缺省的标题可以由调用方传递
        Collection defaults = (Collection)this.hostConfiguration.getParams().getParameter("http.default-headers");
        if(defaults != null) {
            Iterator maxRedirects = defaults.iterator();
            while(maxRedirects.hasNext()) {
                //将自定义的Header设置到Http方法的头部
                method.addRequestHeader((Header)maxRedirects.next());
            }
        }

        try {
            //获取最大重定向次数,如果没有传这个参数则默认重定向100次
            int var9 = this.params.getIntParameter("http.protocol.max-redirects", 100);
            //计数,从0开始
            int redirectCount = 0;
            while(true) {
                if(this.conn != null && !this.hostConfiguration.hostEquals(this.conn)) {
                    //如果此链接存在并且,主机配置相同则先解锁,然后释放此链接
                    this.conn.setLocked(false);
                    this.conn.releaseConnection();
                    this.conn = null;
                }

                if(this.conn == null) {
                    //使用连接管理器根据主机配置参数和超时时间创建链接
                    this.conn = this.connectionManager.getConnectionWithTimeout(this.hostConfiguration, this.params.getConnectionManagerTimeout());
                    //将此条链接锁标记位至锁定状态
                    this.conn.setLocked(true);
                    //由http.authentication.preemptive字段获取这个参数
                    if(this.params.isAuthenticationPreemptive() || this.state.isAuthenticationPreemptive()) {
                        LOG.debug("Preemptively sending default basic credentials");
                        //如果身份验证优先则设置抢占,设置抢占和身份验证
                        method.getHostAuthState().setPreemptive();
                        method.getHostAuthState().setAuthAttempted(true);
                        if(this.conn.isProxied() && !this.conn.isSecure()) {
                            //如果这条链接使用了代理并且是不安全的则,设置代理的抢占和身份验证
                            method.getProxyAuthState().setPreemptive();
                            method.getProxyAuthState().setAuthAttempted(true);
                        }
                    }
                }
                //Http方法获取认证
                this.authenticate(method);
                //执行时重试
                this.executeWithRetry(method);
                if(this.connectMethod != null) {
                    this.fakeResponse(method);
                    break;
                }
                //设置重定向标志位为false
                boolean retry = false;
                if(this.isRedirectNeeded(method) && this.processRedirectResponse(method)) {
                    //如果method方法需要重定向并且重定向响应返回true,则将重定向标志位设置为true
                    retry = true;
                    //重定向计数器加1
                    ++redirectCount;
                    //如果超过了设置的最大重定向数则抛出重定向异常
                    if(redirectCount >= var9) {
                        LOG.error("Narrowly avoided an infinite loop in execute");
                        throw new RedirectException("Maximum redirects (" + var9 + ") exceeded");
                    }

                    if(LOG.isDebugEnabled()) {
                        LOG.debug("Execute redirect " + redirectCount + " of " + var9);
                    }
                }

                if(this.isAuthenticationNeeded(method) && this.processAuthenticationResponse(method)) {
                    //如果method方法需要身份验证且处理身份验证过程响应返回true则将重定向标志位设置为true
                    LOG.debug("Retry authentication");
                    retry = true;
                }
                if(!retry) {
                    //如果重定向为false则执行break;
                    break;
                }

                if(method.getResponseBodyAsStream() != null) {
                    //关闭输入流
                    method.getResponseBodyAsStream().close();
                }
            }
        } finally {
            if(this.conn != null) {
                this.conn.setLocked(false);
            }

            if((this.releaseConnection || method.getResponseBodyAsStream() == null) && this.conn != null) {
                this.conn.releaseConnection();
            }
        }
    }
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值