Przestarzała Java HttpClient - czy to może być trudne?

172

Wszystko, co próbuję zrobić, to pobrać trochę JSON i deserializować go do obiektu. Nie udało mi się jeszcze pobrać JSON.

Prawie każdy przykład HttpClient, który mogę znaleźć, w tym te na stronie Apache, wygląda mniej więcej tak ...

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

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

Jednak Netbeans mówi mi, że DefaultHttpClientjest to przestarzałe. Próbowałem wyszukiwać w googlach DefaultHttpClient deprecatedi tylu innych odmianach, ile mogę wymyślić, i nie mogę znaleźć żadnych przydatnych wyników, więc oczywiście czegoś mi brakuje.

Jaki jest właściwy sposób pobierania zawartości strony internetowej za pomocą języka Java7? Czy naprawdę nie ma przyzwoitego klienta HTTP jako części języka? Trudno mi w to uwierzyć.

Moja zależność od Mavena to ...

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>LATEST</version>
    <type>jar</type>
</dependency>
Podstawowy
źródło
2
NetBeans mówi ci źle lub coś źle odczytujesz. DefaultHttpClientzdecydowanie nie jest przestarzałe. Jaką wersję podałeś w swoim POM?
Percepcja
8
w 4.3-alpha1 wydaje się być przestarzały
Arun P Johny
3
Masz rację, httpclient API to wrak pociągu
Hans Westerbeek
2
Zalecałbym ustawienie wersji na jakiś główny numer wydania zamiast NAJNOWSZEJ. Umożliwi to ręczne sterowanie procesem aktualizacji i nie pozwoli Mavenowi decydować za Ciebie.
Christophe Roussy
1
@Basic może się zmienić w dowolnym momencie podczas pracy nad nim, nawet w nowym projekcie, może to być mylące, jeśli nie ustawiłeś tego samodzielnie. Na przykład zadziałało i skompilowało się, a ty zatwierdzasz kod. Ktoś inny przyjeżdża następnego dnia, kasuje i nawet się nie kompiluje, ponieważ NAJNOWSZA wersja się zmieniła. Oczywiście robisz, co chcesz, ale unikałbym używania go z tego powodu (wersjonowanie).
Christophe Roussy

Odpowiedzi:

259

Odpowiedni przywóz:

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

Stosowanie:

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

EDYCJA (za sugestią Julesa):

Ponieważ build()metoda zwraca CloseableHttpClientktóre jest-a AutoClosable , możesz umieścić deklarację w instrukcji try-with-resources (Java 7+):

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

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

} catch (IOException e) {

    // handle

}
hthserhs
źródło
2
Używasz wersji poniżej 4.3 (i powinna to być Apache HTTPClient, a nie Commons HTTPClient)
Alfishe
7
Zwróć uwagę, że zwracaną wartością jest a CloseableHttpClient, którą należy zamknąć po użyciu. Implementuje AutoCloseable, dzięki czemu można używać go w try-with-zasobów oświadczenia w Javie 7+: try (CloseableHttpClient httpclient = ...) { ... }.
Jules
2
CloseableHttpClient httpClient = HttpClientBuilder.create (). Build (); ta praca dla mnie
Sameer Kazi
6
Pytanie: Czy powinniśmy zatrzymać wystąpienie HttpClientBuilder zwrócone przez create()metodę statyczną? Czy możemy po prostu zadzwonić, create()kiedy tylko będziemy go potrzebować? ... Przy okazji, import org.apache.http.impl.client.HttpClientBuilderdla każdego, kto tego potrzebuje. [Nie lubi odpowiedzi bez instrukcji importu. Nie martw się, nadal zagłosowałem za :)]
ADTC,
1
@HartmutPfitzinger używa OkHttp na Androidzie. Zepsuli rozwidlonego klienta HTTP Apache, który jest teraz starszym.
sschrass
59

IMHO przyjęta odpowiedź jest poprawna, ale pomija pewne „nauczanie”, ponieważ nie wyjaśnia, jak znaleźć odpowiedź. W przypadku wszystkich przestarzałych klas spójrz na JavaDoc (jeśli go nie masz, pobierz lub przejdź do trybu online ), podpowie ona, której klasy użyć do zastąpienia starego kodu. Oczywiście nie powie Ci wszystkiego, ale to jest początek. Przykład:

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

Teraz masz klasę do używania, HttpClientBuilderjak nie ma konstruktora, aby uzyskać budowniczy instancji może się domyślić, że musi istnieć sposób statyczny zamiast: create. Gdy już masz konstruktora, możesz również zgadnąć, że jak w przypadku większości budowniczych istnieje metoda budowania , a zatem:

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

AutoClosable:

Jak zasugerował Jules w komentarzach, zwracana klasa implementuje java.io.Closable, więc jeśli używasz Java 7 lub nowszej, możesz teraz zrobić:

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

Zaletą jest to, że nie musisz zajmować się ostatecznie i zerami.

Inne istotne informacje

Przeczytaj również o buforowaniu połączeń i ustaw limity czasu .

Christophe Roussy
źródło
11

Przykłady z Apache używają tego:

CloseableHttpClient httpclient = HttpClients.createDefault();

Klasa org.apache.http.impl.client.HttpClientsistnieje od wersji 4.3.

Kod HttpClients.createDefault()jest taki sam, jak zaakceptowana odpowiedź tutaj.

IvanRF
źródło
get error „Spowodowany przez: java.lang.VerifyError: org / apache / http / conn / ssl / DefaultHostnameVerifier” podczas używania HttpClient client = HttpClients.createDefault ();
Md Imran Choudhury,
7

Został uznany za przestarzały w wersji, 4.3-alpha1której używasz ze względu na LATESTspecyfikację wersji. Jeśli spojrzysz na javadoc klasy, powie ci, czego zamiast tego użyć:HttpClientBuilder .

W najnowszej stabilnej wersji ( 4.2.3) DefaultHttpClientnie jest jeszcze przestarzały.

zagyi
źródło
Dziękuję za odpowiedź - Netbeans nie pokazuje żadnych JavaDocs dla żadnego elementu org.apache - ale przypuszczam, że to inny problem
Podstawowy
Prawdopodobnie nie masz źródeł dołączonych do biblioteki. Nie używam Netbeans, ale wydaje mi się, że jest sposób, aby poprosić go o pobranie źródeł zależności.
zagyi
7

Spróbuj jcabi-http, który jest płynnym klientem HTTP języka Java, na przykład:

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

Sprawdź także ten wpis na blogu: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

yegor256
źródło
4

Sugerowałbym użycie poniższej metody, jeśli próbujesz odczytać tylko dane 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
źródło
Mówi się, że pytanie DefaultHttpClientjest przestarzałe i sugerujesz użycie go w swojej odpowiedzi ...
Podstawowy
Dzięki za alternatywne podejście. Już zgodziłem się z zaakceptowaną odpowiedzią, ale wygląda to na wystarczająco lekką, że spróbuję następnym razem.
Podstawowy
2

Użyj HttpClientBuilder, aby skompilować HttpClient zamiast używać DefaultHttpClient

dawny:

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

 // Prepare a request object
 HttpGet httpget = new HttpGet("http://www.apache.org/");
Arun P Johny
źródło
Dlaczego new HttpClientBuilder()a nie HttpClientBuilder.create()?
ADTC,
2

Możesz dodać następującą zależność 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>

Możesz użyć następującego importu w swoim kodzie 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;

Możesz użyć następującego bloku kodu w swoim kodzie java.

HttpClient client = HttpClientBuilder.create().build();
HttpUriRequest httpUriRequest = new HttpGet("http://example.domain/someuri");

HttpResponse response = client.execute(httpUriRequest);
System.out.println("Response:"+response);
Czerwony chłopiec
źródło
Dziękuję za poświęcenie czasu na odpowiedź, ale czym różni się to od zaakceptowanej odpowiedzi?
Podstawowy
1
Większość odpowiedzi to kody pseudo, próbowałem wykonać podstawowy działający kod Java od końca do końca za pomocą interfejsu API klienta HTTP Apache wraz z zależnością maven. Jednak nic wielkiego.
Red Boy
1

To jest rozwiązanie, które zastosowałem w przypadku problemu, który httpclient stał się przestarzały w tej wersji Androida 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;
    }
}
Frutos Marquez
źródło
-2

W przypadku pierwotnego wydania proszę o zastosowanie poniższej logiki:

 CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 HttpPost httpPostRequest = new HttpPost();
Pra_A
źródło