Устаревший 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это устарело. Я пробовал поискать в Google DefaultHttpClient deprecatedи столько других вариантов, сколько я могу придумать, и не могу найти никаких полезных результатов, поэтому я явно что-то упускаю.

Какой правильный способ загрузки содержимого веб-страницы на Java7? Неужели нет приличного Http-клиента как части языка? Я считаю, что трудно поверить.

Моя зависимость Maven для этого ...

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

2
NetBeans говорит вам неправильно, или вы что-то неправильно читаете. DefaultHttpClientопределенно не устарела. Какую версию вы указали в своем POM?
— Восприятие

8
в 4.3-alpha1 кажется устаревшим
— Arun P Johny

3
Вы правы, httpclient API - это крушение поезда
— Ханс

2
Я бы порекомендовал вам установить версию на какой-то основной номер выпуска вместо LATEST. Это позволит вам вручную контролировать процесс обновления и не позволит Maven решать за вас.
— Кристоф Русси,

1
@ Основное, оно может измениться в любое время, пока вы работаете над ним, даже в новом проекте, это может сбить с толку, если вы не установили его самостоятельно. Например, это сработало и скомпилировано, и вы фиксируете код. Кто-то еще прибывает на следующий день, оформить заказ, и он даже не компилируется, потому что последняя версия изменилась. Конечно, вы делаете то, что хотите, но я бы по этой причине избегал его использования (версионирование).
— Кристоф Русси,

Ответы:


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 , вы можете разместить объявление в примерочной с-ресурсами заявлении (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

7
Обратите внимание, что возвращаемое значение - это значение CloseableHttpClient, которое вы должны закрывать после использования. Он реализует AutoCloseable, так что вы можете использовать его в заявлении примерочных с-ресурсов в Java 7+: try (CloseableHttpClient httpclient = ...) { ... }.
— Жюль

2
CloseableHttpClient httpClient = HttpClientBuilder.create (). Build (); эта работа для меня
— Самер Кази

6
Вопрос: Должны ли мы удерживать экземпляр HttpClientBuilder, возвращаемый create()статическим методом? Или мы можем просто позвонить, create()когда нам это понадобится? ... Кстати, import org.apache.http.impl.client.HttpClientBuilderдля тех, кто в этом нуждается. [Не любит ответы без импортных заявлений. Не волнуйтесь, я все еще проголосовал :)]
— ADTC

1
@HartmutPfitzinger использовать OkHttp на Android. Они перепутались с разветвленным клиентом Apache Http, который теперь унаследован.
— sschrass

59

ИМХО принятый ответ верен, но пропускает некоторое «учение», так как не объясняет, как придумать ответ. Для всех устаревших классов посмотрите на JavaDoc (если у вас его нет, либо загрузите, либо подключитесь к Интернету ), он подскажет, какой класс использовать для замены старого кода. Конечно, это не скажет вам всего, но это только начало. Пример:

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

Теперь у вас есть класс , чтобы использовать, HttpClientBuilderкак нет конструктора , чтобы получить строитель экземпляр вы можете догадаться , что должен быть статический метод вместо: create. Если у вас есть сборщик, вы также можете догадаться, что, как и для большинства сборщиков, существует метод сборки , таким образом:

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

AutoClosable:

Как намекал Жюль в комментариях, возвращаемый класс реализует java.io.Closable, поэтому, если вы используете Java 7 или выше, теперь вы можете сделать:

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

Преимущество в том, что вам не нужно иметь дело с окончательно и нулевыми значениями.

Другая важная информация

Также не забудьте прочитать о пуле подключений и установить время ожидания .


11

Примеры от Apache используют это:

CloseableHttpClient httpclient = HttpClients.createDefault();

Класс org.apache.http.impl.client.HttpClientsсуществует с версии 4.3.

Код для HttpClients.createDefault()такой же, как принятый ответ здесь.


получить сообщение об ошибке «Причина: java.lang.VerifyError: org / apache / http / conn / ssl / DefaultHostnameVerifier» при использовании HttpClient client = HttpClients.createDefault ();
— Имран Чоудхури

7

Это устарело в версии, 4.3-alpha1которую вы используете из-за LATESTспецификации версии. Если вы посмотрите на Javadoc класса, он говорит вам , что нужно использовать вместо: HttpClientBuilder.

В последней стабильной версии ( 4.2.3) DefaultHttpClientэто не рекомендуется.


Спасибо за ответ - Netbeans не показывает JavaDocs ни для одного из элементов org.apache - но я полагаю, это другая проблема
— Basic

У вас, вероятно, нет источников, прикрепленных к библиотеке. Я не использую Netbeans, но, думаю, есть способ попросить его загрузить источники зависимостей.
— Zagyi


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он устарел, и вы предлагаете использовать его в своем ответе ...
— Basic

Спасибо за альтернативный подход. Я уже согласился с ответом, но он выглядит достаточно легким, чтобы я попробовал в следующий раз.
— Basic

2

Используйте HttpClientBuilder для создания HttpClient вместо использования DefaultHttpClient

например:

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
Большинство ответов относятся к псевдо-кодам. Я попытался создать сквозной базовый рабочий Java-код с API-клиентом Apache HTTP наряду с зависимостью maven. Ничего великого, хотя.
— Red Boy

1

Это решение, которое я применил к проблеме, которую httpclient устарел в этой версии Android 22

 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();
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.