问题背景
最近调平安好医生的接口,发现E3系统超时,导致整个导入任务出于卡死状态,所以需要进行超时改造,这里发现了一个版本的大坑。HttpClient 4.3版本的API变化很大,我们不能去评论说合不合理,只能说改为Closeable也是一件好事,适应一下就可以了。
3.X版本(<4.3)的超时设置
HttpClient httpClient=newDefaultHttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
4.X版本(<4.3)的超时设置
HttpClient httpClient=newDefaultHttpClient();
//连接时间
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,2000);
//数据传输时间
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,2000);
>4.3
版本超时设置
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet=newHttpGet(“https://blog.csdn.net/moshowgame”);//HTTP Get请求(POST雷同)
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();
//设置请求和传输超时时间,10秒超时
httpGet.setConfig(requestConfig);
httpClient.execute(httpGet);//执行请求
public class HttpUtil {
/**
* 按照http4.3改造
* @author zhengkai@blog.csdn.net/moshowgame
* */
public static String post(String url, Map<String, String> params) {
CloseableHttpClient httpclient = HttpClients.createDefault();
//究竟是postBody还是postForm,可以这里调不同的方法
HttpPost httpost = postForm(url, params);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();//设置请求和传输超时时间
httpost.setConfig(requestConfig);
System.out.println("###URL->"+url+"###DATA->"+params.toString());
HttpResponse response = null;
try {
response = httpclient.execute(httpost);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
};
String body = paseResponse(response);
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("###RESPONSE->"+body);
return body;
}
private static HttpPost postBody(String url, String body){
HttpPost httpost = new HttpPost(url);
try {
HttpEntity entity = new StringEntity(body, "utf-8");
httpost.setEntity(entity);
} catch (Exception e) {
e.printStackTrace();
}
return httpost;
}
private static HttpPost postForm(String strUrl, Map<String, String> params){
URL url = null;
URI uri = null;
try {
url = new URL(strUrl);
uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
} catch (URISyntaxException e1) {
e1.printStackTrace();
}catch (MalformedURLException e2) {
e2.printStackTrace();
}
HttpPost httpost = new HttpPost(uri);
List<NameValuePair> nvps = new ArrayList <NameValuePair>();
Set<String> keySet = params.keySet();
for(String key : keySet) {
nvps.add(new BasicNameValuePair(key, params.get(key)));
}
try {
//System.out.println("set utf-8 form entity to httppost");
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return httpost;
}
}
HttpClient超时时间
- 从连接池中获取可用连接超时
setConnectionRequestTimeout
HttpClient中的要用连接时尝试从连接池中获取,若是在等待了一定的时间后还没有获取到可用连接(比如连接池中没有空闲连接了)
则会抛出获取连接超时异常。
- 连接目标超时
setConnectTimeout
指的是连接目标url的连接超时时间,即客服端发送请求到与目标url建立起连接的最大时间。如果在该时间范围内还没有建立起连接,则就
抛出connectionTimeOut异常。如测试的时候,将url改为一个不存在的url:“http://test.com” ,超时时间3000ms过后,系统报出异常:
org.apache.commons.httpclient.ConnectTimeoutException:The host did not accept the connection within timeout of 3000 ms
- 等待响应超时(读取数据超时)
setSocketTimeout
连接上一个url后,获取response的返回等待时间 ,即在与目标url建立连接后,等待放回response的最大时间,在规定时间内没有返回响应的话就抛出SocketTimeout。
测试的时候的连接url为我本地开启的一个url,https://blog.csdn.net/moshowgame,在我这个测试url里,当访问到这个链接时,线程sleep一段时间,来模拟返回response超时。