Застарілий 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 як частини мови? Мені важко повірити.

Моя залежність від Мейвена це ...

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

2
NetBeans говорить вам неправильно, або ви щось неправильно читаєте. DefaultHttpClientточно не застаріло. Яку версію ви вказали у своєму POM?
Сприйняття

8
у 4.3-альфа1 воно, здається, застаріле
Арун П Джонні

3
Ви праві, що httpclient API - це поїзд
Hans Westerbeek

2
Я рекомендую вам встановити версію на якийсь основний номер випуску замість ОСТАННЬОГО. Це дозволить вам вручну контролювати процес оновлення та не дасть 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();

EDIT (за пропозицією Жуля):

Оскільки 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();

Автозакриття:

Як натякав Жуль у коментарях, клас, що повертається, реалізується 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 ();
Md Imran Choudhury

7

У версії, 4.3-alpha1яку ви використовуєте, він застарів через LATESTспецифікацію версії. Якщо ви подивитесь на javadoc класу, він говорить вам, що використовувати замість цього:HttpClientBuilder .

В останній стабільній версії ( 4.2.3) DefaultHttpClientфункція ще не застаріла.


Дякуємо за відповідь - 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


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 для створення 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
Більшість відповідей - це коди psuedo, я намагався виконувати базовий робочий код Java з API Apache HTTP Client API разом із залежністю від maven. Хоча нічого великого.
Червоний хлопчик

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.