Veralteter Java HttpClient - Wie schwer kann es sein?

172

Ich versuche nur, JSON herunterzuladen und in ein Objekt zu deserialisieren. Ich bin noch nicht so weit gekommen, den JSON herunterzuladen.

Fast jedes einzelne HttpClient-Beispiel, das ich finden kann, einschließlich der auf der Apache-Site, sieht ungefähr so ​​aus wie ...

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

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

Netbeans teilt mir jedoch mit, dass dies DefaultHttpClientveraltet ist. Ich habe versucht, nach DefaultHttpClient deprecatedso vielen anderen Variationen zu googeln, wie ich mir vorstellen kann, und kann keine nützlichen Ergebnisse finden, daher fehlt mir offensichtlich etwas.

Was ist der richtige Java7-Weg, um den Inhalt einer Webseite herunterzuladen? Gibt es wirklich keinen anständigen HTTP-Client als Teil der Sprache? Ich finde das schwer zu glauben.

Meine Maven-Abhängigkeit dafür ist ...

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>LATEST</version>
    <type>jar</type>
</dependency>
Basic
quelle
2
NetBeans sagt Ihnen falsch oder Sie lesen etwas falsch. DefaultHttpClientist definitiv nicht veraltet. Welche Version haben Sie in Ihrem POM angegeben?
Wahrnehmung
8
in 4.3-alpha1 scheint es veraltet zu sein
Arun P Johny
3
Sie haben Recht, die httpclient API ist ein Zugunglück
Hans Westerbeek
2
Ich würde empfehlen, dass Sie die Version auf eine Hauptversionsnummer anstelle von LATEST einstellen. Auf diese Weise können Sie den Upgrade-Prozess manuell steuern und Maven nicht für Sie entscheiden lassen.
Christophe Roussy
1
@Basic kann sich jederzeit ändern, während Sie daran arbeiten, auch in einem neuen Projekt. Dies kann verwirrend sein, wenn Sie es nicht selbst festgelegt haben. Zum Beispiel hat es funktioniert und kompiliert und Sie schreiben den Code fest. Jemand anderes kommt am nächsten Tag an der Kasse an und es wird nicht einmal kompiliert, da sich die NEUESTE Version geändert hat. Natürlich machst du was du willst, aber ich würde es aus diesem Grund vermeiden (versionning).
Christophe Roussy

Antworten:

259

Relevante Importe:

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

Verwendung:

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

EDIT (nach Jules 'Vorschlag):

Da das build()Verfahren eine gibt , CloseableHttpClientdie ist-a AutoClosable , können Sie die Erklärung in einer Try-mit-Ressourcen - Anweisung (Java 7+) platzieren:

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

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

} catch (IOException e) {

    // handle

}
hthserhs
quelle
2
Sie verwenden eine Version unter 4.3 (und es sollte Apache HTTPClient sein, nicht Commons HTTPClient)
Alfishe
7
Beachten Sie, dass der Rückgabewert a ist CloseableHttpClient, den Sie nach der Verwendung schließen sollten. Es wird implementiert AutoCloseable, sodass Sie es in einer Try-with-Resources-Anweisung in Java 7+ verwenden können : try (CloseableHttpClient httpclient = ...) { ... }.
Jules
2
CloseableHttpClient httpClient = HttpClientBuilder.create (). Build (); diese Arbeit für mich
Sameer Kazi
6
Frage: Sollten wir an der von der create()statischen Methode zurückgegebenen HttpClientBuilder-Instanz festhalten ? Oder können wir einfach anrufen, create()wann immer wir einen brauchen? ... Übrigens import org.apache.http.impl.client.HttpClientBuilderfür jeden, der das braucht. [Mag keine Antworten ohne Importanweisungen. Keine Sorge, ich habe immer noch positiv gestimmt :)]
ADTC
1
@HartmutPfitzinger benutze OkHttp auf Android. Sie haben einen gespaltenen Apache Http Client durcheinander gebracht, der jetzt ein Vermächtnis ist.
Sschrass
59

IMHO ist die akzeptierte Antwort korrekt, aber es fehlt etwas "Lehren", da es nicht erklärt, wie man auf die Antwort kommt. Schauen Sie sich für alle veralteten Klassen das JavaDoc an (wenn Sie es nicht haben, laden Sie es herunter oder gehen Sie online ), gibt es einen Hinweis darauf, welche Klasse zum Ersetzen des alten Codes verwendet werden soll. Natürlich wird es Ihnen nicht alles erzählen, aber dies ist ein Anfang. Beispiel:

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

Jetzt haben Sie die zu verwendende Klasse HttpClientBuilder, da es keinen Konstruktor gibt, um eine Builder- Instanz abzurufen, können Sie davon ausgehen, dass stattdessen eine statische Methode vorhanden sein muss : create. Sobald Sie den Builder haben, können Sie auch erraten, dass es wie bei den meisten Buildern eine Build-Methode gibt , also:

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

AutoClosable:

Wie Jules in den Kommentaren angedeutet hat, wird die zurückgegebene Klasse implementiert java.io.Closable. Wenn Sie also Java 7 oder höher verwenden, können Sie jetzt Folgendes tun:

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

Der Vorteil ist, dass Sie sich nicht mit finally und nulls befassen müssen.

Andere relevante Informationen

Lesen Sie auch Informationen zum Verbindungspooling und legen Sie die Zeitüberschreitungen fest .

Christophe Roussy
quelle
11

Beispiele aus Apache verwenden dies:

CloseableHttpClient httpclient = HttpClients.createDefault();

Die Klasse org.apache.http.impl.client.HttpClientsist seit Version 4.3 da.

Der Code für HttpClients.createDefault()ist derselbe wie die hier akzeptierte Antwort .

IvanRF
quelle
Fehler "Verursacht durch: java.lang.VerifyError: org / apache / http / conn / ssl / DefaultHostnameVerifier" bei Verwendung von HttpClient client = HttpClients.createDefault ();
Md Imran Choudhury
7

Es wurde in der Version, 4.3-alpha1die Sie verwenden, aufgrund der LATESTVersionsspezifikation veraltet . Wenn Sie sich das Javadoc der Klasse ansehen, erfahren Sie, was Sie stattdessen verwenden sollen : HttpClientBuilder.

In der neuesten stabilen Version ( 4.2.3) DefaultHttpClientist das noch nicht veraltet.

zagyi
quelle
Vielen Dank für die Antwort - Netbeans zeigt keine JavaDocs für die org.apache-Inhalte an - aber ich nehme an, das ist ein anderes Problem
Basic
Sie haben wahrscheinlich nicht die Quellen an die Bibliothek angehängt. Ich verwende keine Netbeans, aber ich denke, es gibt eine Möglichkeit, sie aufzufordern, die Quellen der Abhängigkeiten herunterzuladen.
Zagyi
7

Versuchen Sie jcabi-httpes mit einem fließenden Java-HTTP-Client, zum Beispiel:

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

Überprüfen Sie auch diesen Blog-Beitrag: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

yegor256
quelle
4

Ich würde empfehlen, die folgende Methode zu verwenden, wenn Sie nur die JSON-Daten lesen möchten.

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
quelle
Die Fragen sagen, DefaultHttpClientist veraltet und Sie schlagen vor, es in Ihrer Antwort zu verwenden ...
Basic
Vielen Dank für den alternativen Ansatz. Ich bin bereits mit der akzeptierten Antwort gegangen, aber diese sieht leicht genug aus, dass ich es beim nächsten Mal versuchen werde.
Basic
2

Verwenden Sie HttpClientBuilder die bauen Httpclient anstelle von DefaultHttpClient

Ex:

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

 // Prepare a request object
 HttpGet httpget = new HttpGet("http://www.apache.org/");
Arun P Johny
quelle
Warum new HttpClientBuilder()und nicht HttpClientBuilder.create()?
ADTC
2

Sie können die folgende Maven-Abhängigkeit hinzufügen.

    <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>

Sie können den folgenden Import in Ihren Java-Code verwenden.

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;

Sie können den folgenden Codeblock in Ihrem Java-Code verwenden.

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

HttpResponse response = client.execute(httpUriRequest);
System.out.println("Response:"+response);
Roter Junge
quelle
Vielen Dank, dass Sie sich die Zeit genommen haben, um zu antworten, aber wie unterscheidet sich dies von der akzeptierten Antwort?
Basic
1
Die meisten Antworten sind Pseudocodes. Ich habe versucht, einen durchgängigen, grundlegenden Java-Code mit der Apache HTTP-Client-API zusammen mit der Maven-Abhängigkeit zu erstellen. Nichts großartiges.
Red Boy
1

Dies ist die Lösung, die ich auf das Problem angewendet habe, das httpclient in dieser Version von Android 22 veraltet hat

 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
quelle
-2

Für die ursprüngliche Ausgabe möchte ich Sie bitten, die folgende Logik anzuwenden:

 CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 HttpPost httpPostRequest = new HttpPost();
Pra_A
quelle