不推荐使用的Java HttpClient-有多难?


172

我要做的就是下载一些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 Client吗?我觉得很难相信。

我的Maven依赖关系是...

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

2
NetBeans告诉您错了,或者您误读了某些内容。DefaultHttpClient绝对不建议弃用。您在POM中指定了哪个版本?
感知2013年

8
在4.3-alpha1中似乎已弃用
Arun P Johny

3
您是对的,httpclient API是一次沉船
Hans Westerbeek

2
我建议您将版本设置为一些主要发行版本,而不是“最新”。这将允许您手动控制升级过程,而不会让Maven为您决定。
Christophe Roussy 2014年

1
@Basic可能会随时更改,即使在新项目中也可能会更改,如果您未自行设置,可能会造成混淆。例如,它可以工作并编译,然后提交代码。有人第二天到达,结帐,并且由于最新版本已更改,它甚至无法编译。当然,您可以按照自己的意愿进行操作,但是出于这个原因,我会避免使用它(版本控制)。
Christophe Roussy 2014年

Answers:


259

相关进口:

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是-一个 AutoClosable,你可以放置在一个try-与资源语句(Java 7+)的声明:

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

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

} catch (IOException e) {

    // handle

}

2
您使用的版本低于4.3(应该是Apache HTTPClient,而不是Commons HTTPClient)
Alfishe 2014年

7
请注意,返回值为a CloseableHttpClient,使用后应将其关闭。它实现了AutoCloseable,因此您可以在Java 7+中的try-with-resources语句中使用它try (CloseableHttpClient httpclient = ...) { ... }
Jules

2
CloseableHttpClient httpClient = HttpClientBuilder.create()。build(); 这项工作对我来说
Sameer Kazi 2014年

6
问题:我们是否应该保留create()静态方法返回的HttpClientBuilder实例?还是我们可以create()在需要的时候打电话给我们?……顺便说一句,import org.apache.http.impl.client.HttpClientBuilder为任何需要的人服务。[不喜欢没有导入语句的答案。别担心,我仍然支持:)]
ADTC

1
@HartmutPfitzinger在Android上使用OkHttp。他们搞砸了一个分叉的Apache Http Client,它现在已成为历史。
sschrass '16

59

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

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

现在,你必须使用类HttpClientBuilder,因为没有构造函数来得到一个建设者,你可以猜测,必须有一个静态的方法,而不是实例:create。有了构建器后,您还可以猜测,对于大多数构建器而言,都有一个build方法,因此:

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

可自动关闭:

正如Jules在注释中所暗示的那样,返回的类实现java.io.Closable,因此,如果您使用Java 7或更高版本,则可以执行以下操作:

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

优点是您不必处理final和null。

其他相关信息

另外,请确保阅读有关连接池的信息并设置超时时间


11

来自Apache的示例使用以下代码:

CloseableHttpClient httpclient = HttpClients.createDefault();

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

的代码HttpClients.createDefault()与此处接受的答案相同。


当使用HttpClient客户端= HttpClients.createDefault()时,得到错误“由:java.lang.VerifyError:org / apache / http / conn / ssl / DefaultHostnameVerifier引起”;
伊兰·乔杜里

7

4.3-alpha1由于LATEST版本规范,该版本已弃用。如果你看一看类的javadoc的,它会告诉你,而不是使用什么:HttpClientBuilder

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


感谢您的答复-Netbeans并未针对任何org.apache内容显示任何JavaDocs-但我想这是一个不同的问题
2013年

您可能没有将资源附加到库。我不使用Netbeans,但我想有一种方法可以要求它下载依赖项的源。
zagyi 2013年


4

如果您尝试仅读取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已被弃用,建议您在答案中使用它...
基本的

感谢您的替代方法。我已经接受了正确的答案,但是它看起来很轻便,下次我会尝试一下。
基本

2

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

例如:

MinimalHttpClient httpclient = new HttpClientBuilder().build();

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

为什么new HttpClientBuilder()HttpClientBuilder.create()呢?
ADTC

2

您可以添加以下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);

感谢您抽出宝贵的时间来回答,但这与接受的答案有何不同?
基本的

1
大多数答案都是伪代码,我尝试使用Apache HTTP Client API和maven依赖关系来做端到端的基本工作Java代码。没什么大不了的。
Red Boy

1

这是我已解决此版本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;
    }
}

-2

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

 CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 HttpPost httpPostRequest = new HttpPost();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.