一、HttpClient简介
HttpClient是一个Apache软件基金会下的开源Java HTTP客户端库,支持最新的HTTP/1.1协议规范。HttpClient以URL方式连向服务器并获取数据,因此HttpClient在处理HTTP与HTTPS协议方面表现出色。
使用HttpClient可以轻松地进行HTTP请求。相比于JSoup,HttpClient提供了更多的配置参数、更加丰富的Header设置和HTTP认证等功能,是一个更完善的方案。
在Android开发中,我们经常使用HttpClient下载图片或者数据,因此HttpClient的使用非常重要。
二、HttpClient的网络请求流程
HttpClient的网络请求流程其实也很简单,就是创建HttpClient对象、创建HttpGet/HttpPost对象,最后执行请求并处理响应。具体流程及代码如下:
CloseableHttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(url); HttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); String result = EntityUtils.toString(httpEntity);
首先,我们需要使用HttpClients.createDefault()方法创建一个CloseableHttpClient对象。创建完成后,就可以使用HttpGet或者HttpPost对象进行请求的创建了。
这里以HttpGet为例,使用HttpGet对象可以通过构造函数或者setURI()方法设置请求url。执行请求后,返回一个HttpResponse对象,可以通过获取HttpEntity来获取响应数据。最后使用EntityUtils.toString()方法将HttpEntity转换成String,在进行后续处理。
三、设置请求参数
HttpClient可以非常灵活地定制请求参数,如设置请求头、请求体、连接超时、读取超时、代理等等,下面我们将一一介绍。
1. 设置请求头
我们可以使用setHeader()方法进行自定义请求头,或者使用setDefaultHeaders()方法设置默认请求头,代码如下:
HttpGet httpGet = new HttpGet(url); httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); httpGet.setHeader("Referer", referer);
这里我们设置了User-Agent和Referer两个请求头。User-Agent是指浏览器类型,在不同浏览器中会有不同的值。Referer是指请求发出时所在页面的URL地址,是反映当前请求所在页面的重要标识。
2. 设置请求体
HTTP的POST请求通常需要在请求体中传递数据,HttpClient可以通过setEntity()方法设置请求体。而常用的方法是使用UrlEncodedFormEntity来传递键值对参数,代码如下:
HttpPost httpPost = new HttpPost(url); Listlist = new ArrayList (); list.add(new BasicNameValuePair("username", "123456")); list.add(new BasicNameValuePair("password", "abcdef")); HttpEntity httpEntity = new UrlEncodedFormEntity(list); httpPost.setEntity(httpEntity); HttpResponse httpResponse = httpClient.execute(httpPost); String result = EntityUtils.toString(httpResponse.getEntity());
这里我们使用HttpPost对象,并创建一个List集合来存储键值对参数,最后使用UrlEncodedFormEntity将键值对文本转换为HTTP请求实体。
3. 设置连接超时和读取超时
HttpClient可以进行连接超时和读取超时设置,以确保正常的请求服务和避免请求超时。实现代码如下:
RequestConfig.Builder builder = RequestConfig.custom(); builder.setConnectTimeout(10000); builder.setSocketTimeout(30000); RequestConfig requestConfig = builder.build(); HttpGet httpGet = new HttpGet(url); httpGet.setConfig(requestConfig); HttpResponse httpResponse = httpClient.execute(httpGet);
这里我们通过RequestConfig.Builder进行设置超时时间,设置了10秒的连接超时和30秒的读取超时,最后通过setConfig()方法设置到HttpGet对象中。
4. 设置代理
HttpClient也可以设置代理,以实现一些防爬虫技巧。可以使用HttpHost类来代表代理的主机和端口。代码如下:
HttpHost proxy = new HttpHost("127.0.0.1", 8888); RequestConfig requestConfig = RequestConfig.custom().setProxy(proxy).build(); HttpGet httpGet = new HttpGet(url); httpGet.setConfig(requestConfig); HttpResponse httpResponse = httpClient.execute(httpGet);
这里我们使用HttpHost对象来表示代理主机和端口,然后将其设置到RequestConfig中,并使用setConfig()方法将配置设置到HttpGet对象中。
四、常见问题处理
1. Https请求
HttpClient访问Https请求需要导入SSL证书,否则会报如下异常:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我们可以通过加入信任所有证书的方式解决该问题。代码如下:
public static CloseableHttpClient createSSLClientDefault(){ SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { return true; } }).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); }
其中TrustStrategy表示完全信任请求的网站,也可以自定义信任证书库。
2. 下载文件
HttpClient也可以用来下载文件。我们可以使用HttpGet方法获取InputStream,然后将其写入文件。代码如下:
HttpGet httpGet = new HttpGet(url); HttpResponse httpResponse = httpClient.execute(httpGet); InputStream inputStream = httpResponse.getEntity().getContent(); FileOutputStream fos = new FileOutputStream("D:/test.jpg"); byte[] buffer = new byte[4096]; int length; while ((length = inputStream.read(buffer)) != -1) { fos.write(buffer, 0, length); } fos.flush(); inputStream.close(); fos.close();
3. 大文件下载
对于大文件下载,我们可以使用HttpClient的Range请求处理,分段读取数据,减少网络传输的压力。代码如下:
HttpGet httpGet = new HttpGet(url); httpGet.addHeader("Range", "bytes=0-1024000"); HttpResponse httpResponse = httpClient.execute(httpGet); InputStream inputStream = httpResponse.getEntity().getContent(); FileOutputStream fos = new FileOutputStream("D:/test.jpg"); byte[] buffer = new byte[4096]; int length; while ((length = inputStream.read(buffer)) != -1) { fos.write(buffer, 0, length); } fos.flush(); inputStream.close(); fos.close();
这里我们使用Range请求,限制文件大小为0-1024000字节,就可以分段下载了。
总结
上述就是HttpClient下载的详细介绍,从HttpClient的简介、网络请求流程、设置请求参数、常见问题处理等多个方面做了阐述。掌握了HttpClient下载的使用方法,对于爬虫、Android开发等领域都非常重要。