【问题标题】:Deprecated Java HttpClient - How hard can it be?已弃用的 Java HttpClient - 它有多难?
【发布时间】:2013-02-26 12:07:21
【问题描述】:

我要做的就是下载一些 JSON 并将其反序列化为一个对象。我还没有下载 JSON。

我能找到的几乎每一个 HttpClient 示例,包括 apache 网站上的示例,看起来都类似于...

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;

public void blah() {
    HttpClient client = new DefaultHttpClient();
    ...
}

但是,Netbeans 告诉我 DefaultHttpClient 已被弃用。我已经尝试在谷歌上搜索DefaultHttpClient deprecated 以及我能想到的许多其他变体,但找不到任何有用的结果,所以我显然遗漏了一些东西。

下载网页内容的正确 Java7 方法是什么?作为语言的一部分,真的没有像样的 Http 客户端吗?我觉得这很难相信。

我的 Maven 依赖项是...

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>LATEST</version>
    <type>jar</type>
</dependency>

【问题讨论】:

  • NetBeans 告诉您错误,或者您误读了某些内容。 DefaultHttpClient 绝对不会被弃用。您在 POM 中指定了哪个版本?
  • 在 4.3-alpha1 中似乎已弃用
  • 你说得对,httpclient API 是个火车事故
  • 我建议您将版本设置为某个主要版本号而不是最新版本。这将允许您手动控制升级过程,而不是让 Maven 为您决定。
  • @Basic 即使在新项目中,它也可能在您处理它时随时更改,如果您没有自己设置它可能会造成混淆。例如,它可以工作并编译,然后您提交代码。第二天有人到达,结帐,它甚至没有编译,因为最新版本发生了变化。当然你可以做你想做的事,但出于这个原因我会避免使用它(版本控制)。

标签: java apache-httpclient-4.x apache-commons-httpclient


【解决方案1】:

相关进口:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.IOException;

用法:

HttpClient httpClient = HttpClientBuilder.create().build();

编辑(根据朱尔斯的建议):

由于build() 方法返回一个CloseableHttpClient is-a AutoClosable,您可以将声明放在try-with-resources 语句中(Java 7+):

try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {

    // use httpClient (no need to close it explicitly)

} catch (IOException e) {

    // handle

}

【讨论】:

  • 您使用的是 4.3 以下的版本(应该是 Apache HTTPClient,而不是 Commons HTTPClient)
  • 请注意,返回值为CloseableHttpClient,您应该在使用后关闭它。它实现了AutoCloseable,因此您可以在Java 7+ 中的try-with-resources 语句中使用它:try (CloseableHttpClient httpclient = ...) { ... }
  • CloseableHttpClient httpClient = HttpClientBuilder.create().build();这对我有用
  • 问题:我们应该保留create()静态方法返回的HttpClientBuilder实例吗?或者我们可以在需要时拨打create() 吗?...顺便说一句,import org.apache.http.impl.client.HttpClientBuilder 适合任何需要的人。 [不喜欢没有 import 语句的答案。别担心,我仍然赞成:)]
  • @HartmutPfitzinger 在 Android 上使用 OkHttp。他们搞砸了一个分叉的 Apache Http 客户端,它现在是遗留的。
【解决方案2】:

恕我直言,接受的答案是正确的,但错过了一些“教学”,因为它没有解释如何得出答案。 对于所有已弃用的类,请查看JavaDoc(如果您没有下载它或go online),它将提示使用哪个类来替换旧代码。当然它不会告诉你一切,但这是一个开始。示例:

...
 *
 * @deprecated (4.3) use {@link HttpClientBuilder}.  <----- THE HINT IS HERE !
 */
@ThreadSafe
@Deprecated
public class DefaultHttpClient extends AbstractHttpClient {

现在您有了要使用的类 HttpClientBuilder,因为没有构造函数来获取 builder 实例,您可能会猜测必须有一个静态方法:create。一旦你有了构建器,你也可以猜到大多数构建器都有一个构建方法,因此:

org.apache.http.impl.client.HttpClientBuilder.create().build();

自动关闭:

正如 Jules 在 cmets 中所暗示的,返回的类实现了 java.io.Closable,因此如果您使用 Java 7 或更高版本,您现在可以这样做:

    try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {...}

优点是不用处理finally和null。

其他相关信息

还要确保阅读connection pooling 并设置timeouts

【讨论】:

    【解决方案3】:

    Examples from Apache 使用这个:

    CloseableHttpClient httpclient = HttpClients.createDefault();
    

    org.apache.http.impl.client.HttpClients 从 4.3 版开始就存在。

    HttpClients.createDefault() 的代码与这里的accepted answer 相同。

    【讨论】:

    • 使用 HttpClient 客户端 = HttpClients.createDefault() 时出现错误“由:java.lang.VerifyError: org/apache/http/conn/ssl/DefaultHostnameVerifier 引起”;
    【解决方案4】:

    试试jcabi-http,这是一个流畅的Java HTTP客户端,例如:

    String html = new JdkRequest("https://www.google.com")
      .header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML)
      .fetch()
      .as(HttpResponse.class)
      .assertStatus(HttpURLConnection.HTTP_OK)
      .body();
    

    也请查看这篇博文:http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

    【讨论】:

      【解决方案5】:

      由于LATEST 版本规范,它在您使用的版本4.3-alpha1 中已被弃用。如果您查看该类的 javadoc,它会告诉您改用什么:HttpClientBuilder

      在最新的稳定版本 (4.2.3) 中,DefaultHttpClient 尚未被弃用。

      【讨论】:

      • 感谢您的回复 - Netbeans 没有为任何 org.apache 内容显示任何 JavaDocs - 但我想这是一个不同的问题
      • 您可能没有附加到库的资源。我不使用 Netbeans,但我想有一种方法可以要求它下载依赖项的源代码。
      【解决方案6】:

      如果您只尝试读取 json 数据,我建议使用以下方法。

      URL requestUrl=new URL(url);
      URLConnection con = requestUrl.openConnection();
      BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
      StringBuilder sb=new StringBuilder();
      int cp;
      try {
          while((cp=rd.read())!=-1){
          sb.append((char)cp);
        }
       catch(Exception e){
       }
       String json=sb.toString();
      

      【讨论】:

      • 问题说 DefaultHttpClient 已弃用,您建议在回答中使用它...
      • 感谢您的替代方法。我已经接受了公认的答案,但这看起来很轻巧,下次我会试一试。
      【解决方案7】:

      使用HttpClientBuilder 构建HttpClient 而不是使用 DefaultHttpClient

      例如:

      MinimalHttpClient httpclient = new HttpClientBuilder().build();
      
       // Prepare a request object
       HttpGet httpget = new HttpGet("http://www.apache.org/");
      

      【讨论】:

      • 为什么是new HttpClientBuilder() 而不是HttpClientBuilder.create()
      【解决方案8】:

      您可以添加以下 Maven 依赖项。

          <dependency>
              <groupId>org.apache.httpcomponents</groupId>
              <artifactId>httpclient</artifactId>
              <version>4.5.1</version>
          </dependency>
          <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime -->
          <dependency>
              <groupId>org.apache.httpcomponents</groupId>
              <artifactId>httpmime</artifactId>
              <version>4.5.1</version>
          </dependency>
      

      您可以在您的 java 代码中使用以下导入。

      import org.apache.http.HttpEntity;
      import org.apache.http.HttpResponse;
      import org.apache.http.client.HttpClient;
      import org.apache.http.client.methods.HttpGett;
      import org.apache.http.impl.client.HttpClientBuilder;
      import org.apache.http.client.methods.HttpUriRequest;
      

      您可以在您的 java 代码中使用以下代码块。

      HttpClient client = HttpClientBuilder.create().build();
      HttpUriRequest httpUriRequest = new HttpGet("http://example.domain/someuri");
      
      HttpResponse response = client.execute(httpUriRequest);
      System.out.println("Response:"+response);
      

      【讨论】:

      • 感谢您抽出宝贵时间回答,但这与接受的答案有何不同?
      • 大部分答案都是伪代码,我尝试使用 Apache HTTP 客户端 API 以及 maven 依赖项编写端到端的基本工作 Java 代码。不过没什么大不了的。
      【解决方案9】:

      这是我在这个版本的android 22中不推荐使用httpclient的问题的解决方案

       public static String getContenxtWeb(String urlS) {
          String pagina = "", devuelve = "";
          URL url;
          try {
              url = new URL(urlS);
              HttpURLConnection conexion = (HttpURLConnection) url
                      .openConnection();
              conexion.setRequestProperty("User-Agent",
                      "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
              if (conexion.getResponseCode() == HttpURLConnection.HTTP_OK) {
                  BufferedReader reader = new BufferedReader(
                          new InputStreamReader(conexion.getInputStream()));
                  String linea = reader.readLine();
                  while (linea != null) {
                      pagina += linea;
                      linea = reader.readLine();
                  }
                  reader.close();
      
                  devuelve = pagina;
              } else {
                  conexion.disconnect();
                  return null;
              }
              conexion.disconnect();
              return devuelve;
          } catch (Exception ex) {
              return devuelve;
          }
      }
      

      【讨论】:

        【解决方案10】:

        对于原始问题,我要求您应用以下逻辑:

         CloseableHttpClient httpClient = HttpClientBuilder.create().build();
         HttpPost httpPostRequest = new HttpPost();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-10
          • 1970-01-01
          相关资源
          最近更新 更多