本文基于httpClient4.5版本
maven依赖
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency>
本文不详细展开对httpclient的详细讲解, 只展示具体用法
httpclient 4.5版本设置超时有三种
1connectTimeOut
建立连接超时时间, 众所周知 http的三次握手机智, 在正式进行数据传输之前需要先完成三次握手. connectTimeOut就是指在进行三次握手行为时所设置的超时. 例如在文末例子中,我访问了一个虚假的域名,http://74.125.203.100, 因为域名本身就不存在, 所以三次握手行为肯定是失败的, 所以链接肯定是无法建立的. 根据如下代码, 设置的时间是5000毫秒 所以运行程序会在五秒之后抛出链接超时异常
2socketTimeOut
建立链接成功数据传输导致的超时时间, 当三次握手行为成功后, 即可通过所建立的http通道进行数据传输, 此时如果超过设置时间并没有获取到对应的数据包就会抛出超时异常, 此处有个需要注意点是socketTimeOut所处理的超时时间是指相邻两个数据包传输之间所经历的时间. 例如链接建立成功后 由于数据过大 服务端每隔1秒传送一个数据包给客户端, 此时设置的超时时间为3秒,一共发送了10个数据包,总共耗时10秒, 请求总共花费10秒, 但是并不会报超时异常, 是因为每次数据包传输之间的时间都不超过3秒,所以不会抛出异常, 总结一下 socketTimeOut是指链接建立成功后,数据包传输之间时间超时限制.
3 connectionRequestTimeOut
从httpclient连接池获取连接超时限制 这个超时没有测试, 以后详细解释
时间单位是毫秒
.setConnectionRequestTimeout(1000) // 从数据库连接池获取连接超时时间设置
.setSocketTimeout(1000) // socket连接建立成功, 数据传输响应超时
.setConnectTimeout(5000) // 建立socket链接超时时间
https访问超时无效问题
由于我在项目中既要访问http接口也要访问https接口,设置超时后发现https不起作用,经过排查跟https 对应的HttpClient对象有关,下面贴上新旧代码
初步排查是创建httpsClient时候导致的超时不生效(此时是https接口访问生效, https接口访问不生效), 目前尚未发现是什么原因,待以后详细查看后再解决
旧代码
// 构造方法 public SSLClient() throws Exception{ // 调用父类构造方法 super(); SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }; ctx.init(null, new TrustManager[]{tm}, null); SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); ClientConnectionManager ccm = this.getConnectionManager(); SchemeRegistry sr = ccm.getSchemeRegistry(); sr.register(new Scheme("https", 443, ssf)); }
新代码