一、简介
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。它实现了所有的HTTP方法(GET、POST、PUT、HEAD等),支持自动重定向,支持HTTPS协议,支持代理服务器等丰富的功能。
二、基本的使用
1、创建HttpClient实例
1.1 现在的网站,通常使用SSL证书来保证信息传输的安全性,所以我们需要配置SSL证书,并且绕过证书安全检测。
RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create();
ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
registryBuilder.register("http", plainSF);
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
TrustStrategy anyTrustStrategy = new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] {new X509ExtendedTrustManager() {
//TODO 实现方法体全部为空即可
}}, new SecureRandom());
LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
registryBuilder.register("https", sslSF);
} catch (KeyStoreException e) {
throw new RuntimeException(e);
} catch (KeyManagementException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
Registry<ConnectionSocketFactory> registry = registryBuilder.build();
1.2 HttpClient的连接管理池的配置,这一部分非常重要,缺少某些配置会导致程序中出现难以发现的致命错误。
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);
connManager.setDefaultMaxPerRoute(20);//默认每个连接的最大路由为2个,在这里设置为20,这个太小,在并发时会导致线程挂死
connManager.setMaxTotal(20);//设置连接的最大数
1.3 设置重新请求策略
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception,
int executionCount, HttpContext context) {
if (executionCount >= 3) {
return false;
}
if (exception instanceof NoHttpResponseException) {
return true;
} else if (exception instanceof ClientProtocolException) {
return true;
}else if(exception instanceof SocketTimeoutException){
return true;
}
return false;
}
};
1.4 通常我们需要保存网站的cookie,在HttpClient中BasicCookieStore存储网站的cookie
CookieStore cookieStore = new BasicCookieStore();
1.5 实例化一个HttpClient对象,下面列举常用几个配置项
CloseableHttpClient httpClient = HttpClientBuilder.create()
//.setProxy(new HttpHost("127.0.0.1", 8888)) 设置本地代理
.setConnectionManager(connManager)//设置连接池
.setDefaultCookieStore(cookieStore)//设置cookie存储对象
.setRedirectStrategy(new LaxRedirectStrategy())//设置重定向策略
.setRetryHandler(retryHandler).build();//设置重新请求策略
2、GET、POST请求
request的设置,我们可以更具需要配置请求,例如请求和传输超时时间、设置使用代理,设置是否自动请求转发,相比于在实例HttpClient中设置灵活很多。
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SocketTimeout)
.setConnectTimeout(ConnectTimeout).build();// 设置请求和传输超时时间
2.1 GET请求例子
String url = "https://mail.qq.com"
HttpGet httpGet = new HttpGet(url);//实例httpGet请求
httpGet.setConfig(requestConfig);//设置请求配置
httpGet.addHeader("Accept", "text/plain, */*; q=0.01");//添加请求header
CloseableHttpResponse response = httpClient.execute(httpGet);//执行http请求
2.2 POST请求例子
String url = "https://ssl.qqlogin.com";
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Accept", "/*");
httpPost.setEntity(postDataEntity);//添加post请求参数,常用的有StringEntity和UrlEncodedFormatEntity
CloseableHttpResponse response = httpClient.execute(httpPost);
3 处理请求返回结果
String responseBody = EntityUtils.toString(entity,"utf-8");//返回的结果转换字符串,请求图片后使用EntityUtils.toByteArray(entity)转换为字节数组,在存为图片
EntityUtils.consume(entity);//非常重要,释放此次请求的连接
4 关闭httpClient
httpClient.close();//不在使用httpClient时,手动释放连接
三、其他
HttpClient的强大之处远远不止于此,我们还可以对cookie,响应头做更多的操作;底层源码的cookie校验比较严格,常会导致cookie rejection的警告,有时候需要重写cookie校验工厂类;如果不信任所有连接,并且绕过证书安全检测,请求部分网站会导javax.net.ssl.SSLHandshakeException 这个异常