Устаревший 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

}
hthserhs
источник
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()такой же, как принятый ответ здесь.

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

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

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

zagyi
источник
Спасибо за ответ - Netbeans не показывает JavaDocs ни для одного из элементов org.apache - но я полагаю, это другая проблема
Basic
У вас, вероятно, нет источников, прикрепленных к библиотеке. Я не использую Netbeans, но, думаю, есть способ попросить его загрузить источники зависимостей.
Zagyi
7

Попробуйте 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

yegor256
источник
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();
Anubhab
источник
В вопросе говорится, что 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();
Pra_A
источник