前言:
眼前各位老铁们对“apachecommons学习”可能比较关注,咱们都需要了解一些“apachecommons学习”的相关知识。那么小编在网上搜集了一些对于“apachecommons学习””的相关资讯,希望我们能喜欢,同学们一起来学习一下吧!此文是系列文章第十篇,前几篇请点击链接查看
程序员
程序员的福音 - Apache Commons Lang
程序员的福音 - Apache Commons IO
程序员的福音 - Apache Commons Codec
程序员的福音 - Apache Commons Compress
程序员的福音 - Apache Commons Exec
程序员的福音 - Apache Commons Email
程序员的福音 - Apache Commons Net
程序员的福音 - Apache Commons Collections
Apache HttpClient 组件是为扩展而设计的,同时提供对基本HTTP协议的强大支持。
java.net包提供了通过HTTP访问资源的基本功能,但它并没有提供许多应用程序所需的全部灵活性或功能。HttpClient 组件通过提供一个高效、最新、功能丰富的包来填补这一空白,该包实现了最新HTTP标准的客户端。
HttpClient 过去是 Commons 的一部分,现在是 Apache HttpComponents 的一部分。Apache HttpComponents 是 Apache 的顶级项目,负责创建和维护专注于 HTTP 和相关协议的 Java 组件工具集。因此文章后面将不再使用 Commons HttpClient 字样,而是使用 HttpClient 。
HttpClient 目前有三个大版本,他们是不兼容的,可以同时存在。HttpClient 3过去是 Commons 的一部分,所以一般来说看到 Apache HttpClient 3 的说法指的就是 Commons HttpClient,所属包 org.apache.commons.httpclient,maven 依赖如下
<!-- HttpClient 3 --><dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version></dependency>
HttpClient 4 指的是 Apache HttpComponents 下的项目,所属包 org.apache.http,maven 依赖如下
<!-- HttpClient 4 --><dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version></dependency>
HttpClient 5 指的是 Apache HttpComponents 下的最新项目,包结构是 org.apache.hc,依赖如下
<dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.1</version></dependency>
HttpClient 3 早已不在维护,推荐使用最新的HttpClient 5,截止本文发布时间 2021-08-13,HttpClient 5 在前5天还发布了新版本。HttpClient 5 支持(经典API)(异步API)(反应式API)。
HttpClient 目前最新版本是 5.1,最低要求 Java8 以上。下面我将简单介绍下这几个版本 HttpClient 的用法。
01
—
原生API
我们先来看看如果不使用 HttpClient 而是使用 Java 原生 API,写一个 http 请求的例子
HttpsURLConnection conn = null;try { URL url = new URL(";); conn = (HttpsURLConnection) url.openConnection(); // https请求需要设置证书,为了简单此处默认信任服务器不做证书校验 SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}, new java.security.SecureRandom()); conn.setSSLSocketFactory(sc.getSocketFactory()); conn.setHostnameVerifier((s, sslSession) -> true); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); conn.setUseCaches(false); conn.connect(); InputStream is = conn.getInputStream(); try (BufferedReader br = new BufferedReader( new InputStreamReader(is))) { StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line).append("\n"); } sb.deleteCharAt(sb.length() - 1); println(sb.toString()); }} catch (Exception e) { e.printStackTrace();} finally { if (conn != null) { conn.disconnect(); }}
我们看到这个例子是一个相对比较简单的 https 的 get请求,没有参数。代码已经比较复杂了,如果是 post 请求,需要传递参数,需要保存cookie(有些请求需求登录,我们还要先模拟登录请求后手动将 cookie 保存下来,下次请求再把 cookie 设置上)等场景代码将更为复杂。并且原生 API 默认不支持异步不支持响应式等,这时候就轮到 HttpClient 大显手身了。
02
—
HttpClient 3
HttpClient 3 由于早已不在维护,不支持 http2 和异步等特性,此处只做一个最简单的示例给大家了解一下。注意所属包是 org.apache.commons.httpclient
// httpClient对象是线程安全的,可以单例使用,提升性能HttpClient httpClient = new HttpClient();// 设置连接超时 和 socket超时httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(2000);httpClient.getHttpConnectionManager().getParams().setSoTimeout(5000); // 响应超时HttpMethod getM = new GetMethod(";);// 设置请求头getM.setRequestHeader("Content-Type", "application/json");NameValuePair p1 = new NameValuePair("name", "zs");NameValuePair p2 = new NameValuePair("age", "11");// 设置查询参数,相当于 ?name=zs&age=11getM.setQueryString(new NameValuePair[]{p1, p2});try { int code = httpClient.executeMethod(getM); if (code == HttpStatus.SC_OK) { // 获取结果字符串 String res = getM.getResponseBodyAsString(); // InputStream res = getM.getResponseBodyAsStream(); // 也可以转换为流 System.out.println(res); } else { System.err.println("请求失败,状态码:" + code); }} catch (IOException e) { e.printStackTrace();} finally { // 释放连接资源 getM.releaseConnection();}
03
—
HttpClient 4
HttpClient 4 也不是最新版本,此处也只做一个最简单的示例给大家了解一下。注意所属包是 org.apache.http
// httpClient对象是线程安全的,可以单例使用,提升性能CloseableHttpClient httpClient = HttpClientBuilder.create().build();HttpGet httpGet = new HttpGet(";);httpGet.setHeader("Content-Type", "application/json");RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(2000) // 连接超时 .setConnectionRequestTimeout(2000) // 请求超时 .setSocketTimeout(2000) // 响应超时 .build();httpGet.setConfig(requestConfig);try (CloseableHttpResponse res = httpClient.execute(httpGet)) { int code = res.getStatusLine().getStatusCode(); if (code == HttpStatus.SC_OK) { HttpEntity entity = res.getEntity(); println(EntityUtils.toString(entity, "UTF-8")); } else { System.err.println("请求失败,状态码:" + code); }} catch (IOException e) { System.err.println("请求异常");} finally { httpGet.reset(); // httpGet.releaseConnection(); // 等价于reset()}
04
—
HttpClient 5
HttpClient 5 是目前最新版本。下面将着重介绍下。注意所属包是 org.apache.hc。HttpClient 5 除了包名和 HttpClient 4 有所区别,API的用法大体类似,只有小部分不一致。
建议将 httpClient 作为单例使用,所有请求共用一个 httpClient 对象,这样可以保存 HTTP 的状态,比如登录状态等
1. post请求
// httpClient对象是线程安全的,可以单例使用,提升性能CloseableHttpClient httpClient = HttpClients.createDefault();HttpPost httpPost = new HttpPost(";);RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(Timeout.ofSeconds(2)) .setConnectionRequestTimeout(Timeout.ofSeconds(2)) .setResponseTimeout(Timeout.ofSeconds(2)) .build();httpPost.setConfig(requestConfig);httpPost.setVersion(HttpVersion.HTTP_2); // 支持http2httpPost.setHeader("Content-Type", "application/json");// 支持多种entity参数,字节数组,流,文件等等// 此处使用restful的"application/json",所以传递json字符串httpPost.setEntity(new StringEntity(JSON.toJSONString(paramsObj)));try (CloseableHttpResponse res = httpClient.execute(httpPost)) { if (res.getCode() == HttpStatus.SC_OK) { HttpEntity entity = res.getEntity(); println(EntityUtils.toString(entity)); } else { System.err.println("请求失败,状态码:" + res.getCode()); }} catch (Exception e) { e.printStackTrace();} finally { // 释放连接资源 httpPost.reset();}
2. 重定向支持
有些服务器在可能会返回一个重定向的响应,状态码为302或301,如果是浏览器则会自动向重定向地址发起http请求,HttpClient 5 同样支持此功能,示例如下
CloseableHttpClient httpClient = HttpClients.custom() .disableAutomaticRetries() //关闭自动重试 .setRedirectStrategy(DefaultRedirectStrategy.INSTANCE) .build();// ... ...
3. 异步支持
异步 API 的好处就不说了,HttpClient 5 异步 API 使用 NIO,可以使用少量的线程支持大量的并发,在并发量较大的情况下依然可以保持服务的稳定性和吞吐量。下面看一个简单的例子
CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault();SimpleHttpRequest request = SimpleHttpRequest.create(Method.GET.name(), ";);httpClient.start();httpClient.execute(request, new FutureCallback<SimpleHttpResponse>() { @Override public void completed(SimpleHttpResponse result) { // 响应成功 println(result.getBodyText()); IOUtils.closeQuietly(httpClient); } @Override public void failed(Exception ex) { // 响应出错 ex.printStackTrace(); IOUtils.closeQuietly(httpClient); } @Override public void cancelled() { // 响应取消 println("cancelled"); IOUtils.closeQuietly(httpClient); }});// ... ... 做其他业务处理
05
—
总结
HttpClient 作为 Java HTTP 客户端的工具类,API简单易懂,大大简化了Java HTTP 发送程序的复杂度,并且自动支持 Cookie 功能,GZip 解析,重定向支持,异步支持等等,用来代替 Java 自带的 API 是个不错的选择。
后续章节我将继续给大家介绍 commons 中其他好用的工具类库,期待你的关注。
标签: #apachecommons学习