Apache HttpComponents 的替代品? [关闭]
Posted
技术标签:
【中文标题】Apache HttpComponents 的替代品? [关闭]【英文标题】:Alternatives to Apache HttpComponents? [closed] 【发布时间】:2011-03-24 05:23:48 【问题描述】:所以,我得出的结论是 Apache HttpComponents 4 是我遇到过的最过度使用的 API 之一。看起来应该很简单的事情需要数百行代码(我仍然不确定资源是否得到正确清理)。
此外,它还希望我做以下事情:
List<NameValuePair> qparams = new ArrayList<NameValuePair>();
qparams.add(new BasicNameValuePair("q", "httpclient"));
qparams.add(new BasicNameValuePair("btnG", "Google Search"));
qparams.add(new BasicNameValuePair("aq", "f"));
qparams.add(new BasicNameValuePair("oq", null));
URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search",
URLEncodedUtils.format(qparams, "UTF-8"), null);
哪个,只是……不。我知道它是 Java,我们对整个简洁性并不感兴趣,但这有点多。更不用说这些 jar 文件高达 700KB。
不管怎样,废话不多说,我想看看人们对其他 HTTP 客户端库有什么样的体验?
我知道的有:Jetty、hotpotato 和 AsyncHttpClient。
这是供服务器端使用的,我最感兴趣的是许多并发获取和大文件传输的性能。
有什么建议吗?
PS 我知道古老的 HttpClient 3.1 仍然存在,但我想使用受支持的东西。
更新
@oleg:这是文档的建议:
HttpClient httpclient = new DefaultHttpClient();
try
HttpGet httpget = new HttpGet("http://www.apache.org/");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null)
InputStream instream = entity.getContent();
try
instream.read();
catch (IOException ex)
throw ex;
catch (RuntimeException ex)
httpget.abort();
throw ex;
finally
try instream.close(); catch (Exception ignore)
finally
httpclient.getConnectionManager().shutdown();
在使用ThreadSafeClientConnManager
时使用实体内容时,我仍然会遇到意外错误。我确定这是我的错,但在这一点上,我真的不想弄清楚。
嘿,我并不是要贬低任何人在这里的工作,但自从 4.0 发布以来,我一直在努力使用 HttpComponents,但它对我不起作用。
【问题讨论】:
虽然不是完美无缺,但您是否考虑过标准的 URLConnection/HTTPUrlConnection ? 必须调用 InputStream#close() 来释放分配的资源是非常复杂的,不是吗? 自 4.0 以来,API 随每个点发布而改变的次数比我更换内衣的次数还要多 @RTF 我不认识你,所以我不知道 API 是否变化很快,或者我是否应该避免闻到你家的味道:D @Joffrey A 列的一点点,B 列的一点点 【参考方案1】:HttpClient API 的复杂性只是反映了其问题域的复杂性。与流行的误解相反,HTTP 是一个相当复杂的协议。作为一个低级传输库 HC 4.0 API 主要针对性能和灵活性而不是简单性进行了优化。很遗憾你无法弄清楚,但就这样吧。欢迎您使用最适合您需求的任何库。我个人非常喜欢Jetty HttpClient。这是一个很好的选择,可能对您更有效。
【讨论】:
我同意你 (+1) 和 OP。功能和灵活性是必要的,但在某个地方还应该有一组外观方法来简化流程。public static InputStream httpGetAsStream(String baseUrl, Map<String, Object> parameters)
等方法
HTTP 很复杂,但 Apache 的 HttpComponents 库 设计过度可笑,并且包含许多对协议操作而言并非必不可少的复杂性。客观上它有一个非常糟糕的 API。
@Alex B:HttpComponents 被用于各种不同的应用程序中,从简单的 URL 获取器到复杂的传输和具有不同且经常相互冲突的需求的网络爬虫。对某些人来说似乎无关紧要的东西,对另一些人来说却是绝对必要的。 HttpClient 必须处理几十个自定义参数和上下文特定的策略和对象。因此,灵活性必须先于简单性。对于那些无法理解 HttpClient API 的人,可以使用流畅的外观 API:hc.apache.org/httpcomponents-client-dev/fluent-hc/index.html
“HttpClient API 的复杂性只是反映了其问题域的复杂性。” 如果 HC 4.0 是完美的,那将是一个好点,但事实并非如此。它有很多问题,我想缺乏方向会导致它陷入今天的混乱局面。我认为 Alex B 是对的,他客观地说 API 很糟糕,本可以好多更好。本来可以的。
@SeanPatrickFloyd there should be a set of façade methods
确实有有这样一组方法:Apache HttpComponents Fluent API。 (正如 oleg 在上面的评论中指出的那样)【参考方案2】:
对于简单的用例,您可以使用HttpClient Fluent API。见tutorials。
该模块基于流畅接口的概念为 HttpClient 提供了一个易于使用的外观 API。 Fluent 外观 API 仅公开 HttpClient 的最基本功能,并且适用于不需要 HttpClient 完全灵活性的简单用例。例如,流畅的外观 API 使用户不必处理连接管理和资源释放
// Execute a GET with timeout settings and return response content as String.
Request.Get("http://somehost/")
.connectTimeout(1000)
.socketTimeout(1000)
.execute().returnContent().asString();
Maven 工件。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.2.5</version>
</dependency>
【讨论】:
更新:现在有很多更好的选择。 OkHttp 和 Retrofit 是非常棒的库,它们简洁且功能完善,适用于大多数现代应用程序。【参考方案3】:回答我自己的问题,因为它因某种原因复活了。
我最终围绕java.net.HttpURLConnection
编写了一些简单的包装器,似乎距离我上次认真考虑它已经走了很长一段路。
Apache HttpComponents 很棒,但对于简单的任务可能有点过分了。此外,至少在我的场景中,HUC 明显更快(主要是单线程,没有在重负载下进行任何测试)。
【讨论】:
HttpURLConnection 实例的创建成本明显低于它们共享一个静态 JRE 范围的连接池这一事实。默认情况下,HttpClient 总是创建一个新的连接池,因此启动和预热速度较慢。可以通过对新请求重新使用相同的 HttpClient 实例来解决此问题。这种方法被 HttpClient 的流利外观使用,例如:hc.apache.org/httpcomponents-client-dev/fluent-hc/index.html。在所有其他情况下,我认为 HttpClient 应该更快 也许我做错了什么,这并不是严格的基准测试。我总是使用单个 HttpClient 实例。刚刚运行了一个快速测试:从 localhost 获取非常小的文档(150 字节)x 5000 次,使用 HttpClient (4.1) 大约需要 10 秒,使用 HUC 大约需要 2 秒。这实际上不仅仅是学术性的,我的主要用例是在同一台机器上针对服务进行大量小型查找。 我只能给你我的(有偏见的)观点。任何持续 2 秒的 HTTP 性能测试根本不具有代表性。需要运行基准测试几分钟才能获得或多或少可靠的数字。这是我们内部使用的基准测试和一些结果:wiki.apache.org/HttpComponents/…。与 HUC 和其他客户端相比,HttpClient 4.x 的性能似乎还不错。 当然。就像我说的,这绝不是一个全面的基准。再说一次,在您的基准测试未涵盖的 my 特定情况下,存在明显的差异。我不会对此进行概括(当然不具代表性),但它确实会影响我决定在我的场景中使用什么。【参考方案4】:jsoup
jsoup 是一个旨在解析 HTML 文件的库。它确实会进行 HTTP 调用以检索网页的源代码。
Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
【讨论】:
【参考方案5】:Google HTTP 客户端
另一个库是Google HTTP Client Library for Java。
该库由 Google 编写,是一个灵活、高效且功能强大的 Java 客户端库,用于通过 HTTP 访问网络上的任何资源。它具有可插入的 HTTP 传输抽象,允许使用任何低级库,例如 java.net.HttpURLConnection、Apache HTTP 客户端或 Google App Engine 上的 URL Fetch。它还具有高效的 JSON 和 XML 数据模型,用于解析和序列化 HTTP 响应和请求内容。 JSON 和 XML 库也是完全可插拔的,包括对 Jackson 和 android 的 JSON 的 GSON 库的支持。
【讨论】:
【参考方案6】:您可以使用Netty 或Apache Mina,尽管它们的级别非常低,而且我不确定您最终会得到不那么冗长的代码。
【讨论】:
【参考方案7】:我非常喜欢 JAX-RS 的客户端 API(在 2.0 中标准化),尤其是 Jersey 的实现。它支持异步并具有connectors,因此它可以得到 Apache HttpComponents、普通 HttpUrlConnection、Jetty 或 Grizzly 的支持。
here 有一些很好的用法示例,包括以下内容。
client.target(REST_SERVICE_URL)
.path("/bookId")
.resolveTemplate("bookId", bookId)
.request()
.get(Book.class);
【讨论】:
【参考方案8】:HTTPUnit 有一个很棒的界面(不需要太多代码),但它的最新版本会提交重复的请求。
HTMLUnit 可以工作,但对我来说,它似乎对 javascript 的支持有限。我有 不过可以将它用于基本网页。
【讨论】:
【参考方案9】:您可以查看Restlet 的客户端功能。它是上面的一层,可以被 Apache HttpComponents 或 Java 的 Net API 支持。
【讨论】:
我使用了 Jersey 的客户端,它在概念上非常相似。在很多情况下都非常方便。以上是关于Apache HttpComponents 的替代品? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Apache HttpComponents 工具类 [ HttpUtil ]
Gradle 无法解析依赖组:org.apache.httpcomponents,模块:httpmime
org.apache.httpcomponents.httpclient