前言
平时做爬虫比较多,我的第一个爬虫,就是用Java的jsoup写的。爬虫说白了就是对各种网页进行请求,而发起请求就需要用到HTTP的工具库。今天就来枚举一下Java中常用的各种工具库,从代码层面分析它们的优点和缺点。
HttpURLConnection
HttpURLConnection是Java标准库java.net自带的原生HTTP客户端,Jsoup就是基于HttpURLConnection实现的,我们这里使用HttpURLConnection来实现一个简单的请求,来探究他的用法。
String start_url = "http://www.baidu.com";
URL url = new URL(start_url);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
int status = con.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
System.out.println(content.toString());
} else {
System.out.println("状态码:" + status);
}
con.disconnect();
执行代码:
可以看到,HttpURLConnection使用起来比较简单,能让使用者更好地理解请求和响应的过程。但是使用者需要调用基础的api,例如创建URL,获取响应数据,需要编写大量代码。
Apache HttpClient
引入HttpClient依赖:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
使用HttpClient实现简单的请求代码。
String start_url = "http://www.baidu.com";
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(start_url);
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "utf-8");
System.out.println("服务器返回的数据: " + result);
}
} catch (IOException e) {
e.printStackTrace();
}
执行程序,也输出了百度的首页内容。除了这种简单的用法,httpclient支持请求头等设置:
// 设置请求头
httpGet.addHeader("Content-Type", "application/json");
// 设置连接和读取超时时间
httpGet.setParams(RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build());
还可以使用连接池提高性能:
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(100);
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.build();
除此之外,还提供了灵活的配置选项和多种定制功能,适用于处理复杂的HTTP请求身份认证、重定向、添加代理等功能。
但是过多的配置选项会让人初次使用的人产生迷茫的感觉。尤其是初学者。我在2018年第一次使用HttpClient中就对各种参数配置产生过迷茫。
OkHttp
在日常工作中,OkHttp用的比较多。从官网了解到oKHttp有以下优点:
- HTTP/2支持允许对同一主机的所有请求共享一个套接字。
- 连接池减少了请求延迟(。
- 透明压缩(Transparent GZIP )缩小了交互数据的大小,减轻了网络I/O负担
- 响应缓存完全避免了网络重复请求
- 当网络出现问题时,OkHttp会从常见的连接问题中静默地恢复
然后研究了一下api,看看使用OkHttp发起http请求如何实现。
String start_url = "http://www.baidu.com";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(start_url)
.build();
try {
Response response = client.newCall(request).execute();
ResponseBody responseBody = response.body();
if (responseBody != null) {
String result = responseBody.string();
System.out.println("服务器返回的数据: " + result);
}
} catch (IOException e) {
e.printStackTrace();
}
执行代码输出请求:
感觉没啥缺点。。
Spring RestTemplate
Spring框架集成了RestTemplate,作为HTTP客户端依赖Spring框架,对于非Spring应用可能不太适用。
结语
上面就是我日常开发中遇到过的Http的工具库。从上面看,每种HTTP库都有自己的优势和劣势。开发者可以根据项目的具体需求来选择合适的HTTP库。对于初学者来说,可以使用HttpURLConnection进行学习,了解HTTP的请求响应其实就是I/O操作
对于复杂的HTTP请求,可以考虑使用Apache HttpClient或OkHttp,但从实际的开发应用中OkHttp使用是最广泛的,尤其是对高并发的场景。