Wie kann ich in Java einen http-Antworttext als Zeichenfolge abrufen?

155

Ich weiß, dass es früher eine Möglichkeit gab, es mit Apache Commons zu bekommen, wie hier dokumentiert: http://hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpMethod.html und ein Beispiel hier:

http://www.kodejava.org/examples/416.html

aber ich glaube, das ist veraltet. Gibt es eine andere Möglichkeit, eine http-Get-Anfrage in Java zu erstellen und den Antworttext als Zeichenfolge und nicht als Stream abzurufen?

Dänisch94
quelle
1
Da es sich bei der Frage und allen Antworten anscheinend um Apache-Bibliotheken handelt, sollte dies als solche gekennzeichnet werden. Ich sehe nichts ohne die Verwendung von 3rdparty-Bibliotheken.
Eis

Antworten:

104

Jede Bibliothek, an die ich denken kann, gibt einen Stream zurück. Sie könnten verwenden IOUtils.toString()von Apache Commons IO eine zu lesen , InputStreamin einen Stringin einem Methodenaufruf. Z.B:

URL url = new URL("http://www.example.com/");
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();
encoding = encoding == null ? "UTF-8" : encoding;
String body = IOUtils.toString(in, encoding);
System.out.println(body);

Update: Ich habe das obige Beispiel geändert, um die Inhaltscodierung aus der Antwort zu verwenden, falls verfügbar. Andernfalls wird standardmäßig UTF-8 verwendet, anstatt die Standardeinstellung des lokalen Systems zu verwenden.

WhiteFang34
quelle
4
Dies wird in vielen Fällen den Text beschädigen, da die Methode die Standardtextcodierung des Systems verwendet, die je nach Betriebssystem und Benutzereinstellungen variiert.
McDowell
1
@ McDowell: Hoppla, danke, ich habe das Javadoc für die Methode mit der Codierung verknüpft, aber ich habe vergessen, es im Beispiel zu verwenden. Ich habe dem Beispiel vorerst UTF-8 hinzugefügt, obwohl technisch gesehen der Content-EncodingHeader aus der Antwort verwendet werden sollte, falls verfügbar.
WhiteFang34
Gute Verwendung von IOUtils. Netter praktischer Ansatz.
Spidey
8
Tatsächlich wird der Zeichensatz in contentType wie "charset = ..." angegeben, jedoch nicht in contentEncoding, das so etwas wie "gzip" enthält
Timur Yusupov
1
Diese Funktion bewirkt, dass der Eingabestream geschlossen wird. Gibt es eine Möglichkeit @ WhiteFang34 Ich kann meine Antwort drucken und weiterhin die http-Entität verwenden
amIT
274

Hier sind zwei Beispiele aus meinem Arbeitsprojekt.

  1. Verwenden von EntityUtilsundHttpEntity

    HttpResponse response = httpClient.execute(new HttpGet(URL));
    HttpEntity entity = response.getEntity();
    String responseString = EntityUtils.toString(entity, "UTF-8");
    System.out.println(responseString);
  2. Verwenden von BasicResponseHandler

    HttpResponse response = httpClient.execute(new HttpGet(URL));
    String responseString = new BasicResponseHandler().handleResponse(response);
    System.out.println(responseString);
spinnennetz
quelle
10
Das einzige Problem, mit dem ich bei Methode 1 konfrontiert war, ist, dass das Entitätsobjekt dabei verbraucht wird response.getEntity()und jetzt als verfügbar ist responseString. Wenn Sie erneut versuchen, eine response.getEntity () auszuführen, wird diese zurückgegeben IllegalStateException.
Tirtha
In meinem Fall hat es funktioniert - den Körper von der CloseableHttpClient-Antwort zu bekommen.
Jaroslav Štreit
1
Was ist httpClient?!
Andreas L.
1
@AndreasL. Httpclient ist vom Typ Httpclient (org.apache.commons.httpclient package)
spideringweb
Es ist so üblich, den Antwortinhalt als String- oder Byte-Array oder so etwas abzurufen. Wäre schön mit einer API direkt auf Entity, um Ihnen das zu geben. Ich muss danach suchen, um diese util-Klasse zu finden.
Claus Ibsen
52

Hier ist ein Beispiel aus einem anderen einfachen Projekt, an dem ich mit der httpclient-Bibliothek von Apache gearbeitet habe:

String response = new String();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("j", request));
HttpEntity requestEntity = new UrlEncodedFormEntity(nameValuePairs);

HttpPost httpPost = new HttpPost(mURI);
httpPost.setEntity(requestEntity);
HttpResponse httpResponse = mHttpClient.execute(httpPost);
HttpEntity responseEntity = httpResponse.getEntity();
if(responseEntity!=null) {
    response = EntityUtils.toString(responseEntity);
}

Verwenden Sie einfach EntityUtils, um den Antworttext als String abzurufen. sehr einfach.

Mondscheinkäse
quelle
28

Dies ist im speziellen Fall relativ einfach, im allgemeinen Fall jedoch recht schwierig.

HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://stackoverflow.com/");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println(EntityUtils.getContentMimeType(entity));
System.out.println(EntityUtils.getContentCharSet(entity));

Die Antwort hängt vom Content-Type HTTP-Antwortheader ab .

Dieser Header enthält Informationen zur Nutzlast und kann die Codierung von Textdaten definieren. Selbst wenn Sie von Texttypen ausgehen , müssen Sie möglicherweise den Inhalt selbst überprüfen, um die richtige Zeichenkodierung zu ermitteln. Weitere Informationen dazu finden Sie in der HTML 4-Spezifikation für das jeweilige Format.

Sobald die Codierung bekannt ist, kann ein InputStreamReader zum Decodieren der Daten verwendet werden.

Diese Antwort hängt davon ab, ob der Server das Richtige tut. Wenn Sie Fälle behandeln möchten, in denen die Antwortheader nicht mit dem Dokument übereinstimmen oder die Dokumentdeklarationen nicht mit der verwendeten Codierung übereinstimmen, ist dies ein weiterer Fischkessel.

McDowell
quelle
Wie bekomme ich es als HashMap? Ich bekomme eine Antwort als Json, wie soll ich das lesen?
user1735921
10

Im Folgenden finden Sie eine einfache Möglichkeit, mithilfe der Apache HTTP Client-Bibliothek als Zeichenfolge auf die Antwort zuzugreifen.

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;

//... 

HttpGet get;
HttpClient httpClient;

// initialize variables above

ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpClient.execute(get, responseHandler);
lkamal
quelle
9

Wie wäre es nur damit?

org.apache.commons.io.IOUtils.toString(new URL("http://www.someurl.com/"));
Eric Schlenz
quelle
9

Die Antwort von McDowell ist richtig. Wenn Sie jedoch in einigen der oben genannten Beiträge einen anderen Vorschlag versuchen.

HttpEntity responseEntity = httpResponse.getEntity();
if(responseEntity!=null) {
   response = EntityUtils.toString(responseEntity);
   S.O.P (response);
}

Dann erhalten Sie eine illegalStateException, die besagt, dass der Inhalt bereits verbraucht ist.

Akshay
quelle
3

Wir können den folgenden Code auch verwenden, um die HTML-Antwort in Java zu erhalten

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.HttpResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.apache.log4j.Logger;

public static void main(String[] args) throws Exception {
    HttpClient client = new DefaultHttpClient();
    //  args[0] :-  http://hostname:8080/abc/xyz/CheckResponse
    HttpGet request1 = new HttpGet(args[0]);
    HttpResponse response1 = client.execute(request1);
    int code = response1.getStatusLine().getStatusCode();

    try (BufferedReader br = new BufferedReader(new InputStreamReader((response1.getEntity().getContent())));) {
        // Read in all of the post results into a String.
        String output = "";
        Boolean keepGoing = true;
        while (keepGoing) {
            String currentLine = br.readLine();

            if (currentLine == null) {
                keepGoing = false;
            } else {
                output += currentLine;
            }
        }

        System.out.println("Response-->" + output);
    } catch (Exception e) {
        System.out.println("Exception" + e);

    }
}
Subhasish Sahu
quelle
Dies ist eine sehr gute Antwort, dies ist, was ich anzeigen muss, die Antwort nach dem Posten von Daten auf dem Server. Gut gemacht.
SlimenTN
0

Hier ist eine einfache Möglichkeit, dies zu tun:

String responseString = "";
for (int i = 0; i < response.getEntity().getContentLength(); i++) { 
    responseString +=
    Character.toString((char)response.getEntity().getContent().read()); 
}

Natürlich responseStringmit der Antwort der Website und der Art der Antwort, die von HttpResponsezurückgegeben wirdHttpClient.execute(request)

Marko Zajc
quelle
0

Das folgende Codefragment zeigt, wie der Antworttext besser als Zeichenfolge behandelt werden kann, unabhängig davon, ob es sich um eine gültige Antwort oder eine Fehlerantwort für die HTTP-POST-Anforderung handelt:

BufferedReader reader = null;
OutputStream os = null;
String payload = "";
try {
    URL url1 = new URL("YOUR_URL");
    HttpURLConnection postConnection = (HttpURLConnection) url1.openConnection();
    postConnection.setRequestMethod("POST");
    postConnection.setRequestProperty("Content-Type", "application/json");
    postConnection.setDoOutput(true);
    os = postConnection.getOutputStream();
    os.write(eventContext.getMessage().getPayloadAsString().getBytes());
    os.flush();

    String line;
    try{
        reader = new BufferedReader(new InputStreamReader(postConnection.getInputStream()));
    }
    catch(IOException e){
        if(reader == null)
            reader = new BufferedReader(new InputStreamReader(postConnection.getErrorStream()));
    }
    while ((line = reader.readLine()) != null)
        payload += line.toString();
}       
catch (Exception ex) {
            log.error("Post request Failed with message: " + ex.getMessage(), ex);
} finally {
    try {
        reader.close();
        os.close();
    } catch (IOException e) {
        log.error(e.getMessage(), e);
        return null;
    }
}
Krutik
quelle
0

Sie können eine 3D-Party-Bibliothek verwenden, die eine HTTP-Anfrage sendet und die Antwort verarbeitet. Eines der bekanntesten Produkte wäre Apache Commons HTTPClient: HttpClient javadoc , HttpClient Maven Artefakt . Es gibt einen weitaus weniger bekannten, aber viel einfacheren HTTPClient (Teil einer von mir geschriebenen Open-Source-MgntUtils-Bibliothek): MgntUtils HttpClient javadoc , MgntUtils-Maven-Artefakt , MgntUtils Github . Mit einer dieser Bibliotheken können Sie Ihre REST-Anfrage senden und als Teil Ihrer Geschäftslogik unabhängig von Spring eine Antwort erhalten

Michael Gantman
quelle
0

Wenn Sie Jackson verwenden, um den Antwortkörper zu deserialisieren, besteht eine sehr einfache Lösung darin, request.getResponseBodyAsStream()anstelle von zu verwendenrequest.getResponseBodyAsString()

Vic Seedoubleyew
quelle