Come posso ottenere un corpo di risposta http come stringa in Java?


155

So che c'era un modo per ottenerlo con i comuni Apache come documentato qui: http://hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpMethod.html e un esempio qui:

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

ma credo che questo sia deprecato. C'è un altro modo per fare in modo che un HTTP riceva una richiesta in Java e ottenga il corpo della risposta come una stringa e non come un flusso?


1
Poiché la domanda e tutte le risposte sembrano riguardare le librerie apache, questo dovrebbe essere etichettato come tale. Non vedo nulla senza usare le librerie di terze parti.
eis,

Risposte:


104

Ogni libreria a cui riesco a pensare restituisce un flusso. Si potrebbe utilizzare IOUtils.toString()da Apache Commons IO di leggere un InputStreamin una Stringin una chiamata di metodo. Per esempio:

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

Aggiornamento: ho modificato l'esempio sopra per utilizzare la codifica del contenuto dalla risposta, se disponibile. Altrimenti, per impostazione predefinita, verrà utilizzato UTF-8, anziché utilizzare l'impostazione predefinita del sistema locale.


4
ciò corromperà il testo in molti casi poiché il metodo utilizza la codifica di testo predefinita del sistema che varia in base al sistema operativo e alle impostazioni dell'utente.
McDowell,

1
@McDowell: oops grazie, ho collegato javadoc per il metodo con la codifica ma ho dimenticato di usarlo nell'esempio. Ho aggiunto UTF-8 all'esempio per ora, anche se tecnicamente dovrei usare l' Content-Encodingintestazione della risposta, se disponibile.
WhiteFang34

Ottimo utilizzo di IOUtils. Bel approccio pratico.
Spidey,

8
In realtà charset è specificato in contentType come "charset = ...", ma non in contentEncoding, che contiene qualcosa come "gzip"
Timur Yusupov

1
questa funzione provoca la chiusura del flusso di input, c'è un modo @ WhiteFang34 posso stampare la mia risposta e continuare a utilizzare l'entità http
amIT

274

Ecco due esempi del mio progetto di lavoro.

  1. Utilizzando EntityUtilseHttpEntity

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

    HttpResponse response = httpClient.execute(new HttpGet(URL));
    String responseString = new BasicResponseHandler().handleResponse(response);
    System.out.println(responseString);

10
L'unico problema che ho riscontrato con il metodo 1 è che l'oggetto entità viene consumato quando lo fai response.getEntity()e ora è disponibile come responseString. se si tenta di eseguire nuovamente response.getEntity (), verrà restituito IllegalStateException.
Tirtha,

Ha funzionato nel mio caso - ottenere il corpo dalla risposta CloseableHttpClient.
Jaroslav Štreit,

1
Che cos'è httpClient ?!
Andreas L.

1
@AndreasL. httpClient è di tipo HttpClient (pacchetto org.apache.commons.httpclient)
spideringweb

È così comune ottenere il contenuto della risposta come stringa o array di byte o altro. Sarebbe bello con un'API direttamente su Entity dartelo. Dovendo cercare questo per trovare questa classe util.
Claus Ibsen il

52

Ecco un esempio di un altro semplice progetto a cui stavo lavorando utilizzando la libreria httpclient di Apache:

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);
}

basta usare EntityUtils per afferrare il corpo della risposta come una stringa. molto semplice.


28

Questo è relativamente semplice nel caso specifico, ma piuttosto complicato nel caso generale.

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

La risposta dipende Content-Type dall'intestazione della risposta HTTP .

Questa intestazione contiene informazioni sul payload e potrebbe definire la codifica dei dati testuali. Anche se si assumono tipi di testo , potrebbe essere necessario ispezionare il contenuto stesso per determinare la codifica dei caratteri corretta. Ad esempio, vedi le specifiche HTML 4 per i dettagli su come farlo per quel particolare formato.

Una volta conosciuta la codifica, è possibile utilizzare un InputStreamReader per decodificare i dati.

Questa risposta dipende dal fatto che il server stia facendo la cosa giusta: se si desidera gestire i casi in cui le intestazioni di risposta non corrispondono al documento o le dichiarazioni del documento non corrispondono alla codifica utilizzata, si tratta di un altro bollitore di pesce.


come ottenerlo come HashMap? Ricevo risposta come Json, come leggerlo?
user1735921

10

Di seguito è riportato un modo semplice per accedere alla risposta come stringa utilizzando la libreria client HTTP Apache.

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

9

Che ne dici di questo?

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

9

La risposta di McDowell è corretta. Tuttavia, se provi altri suggerimenti in alcuni dei post sopra.

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

Quindi ti darà illegaleStateException indicando che il contenuto è già consumato.


3

Possiamo usare il codice seguente anche per ottenere la risposta HTML in Java

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

    }
}

Questa è un'ottima risposta, questo è ciò che devo visualizzare, la risposta dopo aver pubblicato i dati sul server. Molto bene.
SlimenTN,

0

Ecco un modo leggero per farlo:

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

Naturalmente responseStringcontenente la risposta del sito Web e il tipo di risposta HttpResponse, restituito daHttpClient.execute(request)


0

Di seguito è riportato lo snippet di codice che mostra il modo migliore di gestire il corpo della risposta come stringa, sia che si tratti di una risposta valida o di una risposta di errore per la richiesta POST HTTP:

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

0

È possibile utilizzare una libreria di terze parti che invia la richiesta HTTP e gestisce la risposta. Uno dei prodotti più noti sarebbe HTTPClient comune di Apache: HttpClient javadoc , artefatto HttpClient Maven . C'è HTTPClient di gran lunga meno conosciuto ma molto più semplice (parte di una libreria MgntUtils open source scritta da me): MgntUtils HttpClient javadoc , MgntUtils maven artefatto , MgntUtils Github . Utilizzando una di queste librerie è possibile inviare la richiesta REST e ricevere risposte indipendentemente da Spring come parte della propria logica aziendale


0

Se stai usando Jackson per deserializzare il corpo della risposta, al request.getResponseBodyAsStream()posto di utilizzare una soluzione molto semplicerequest.getResponseBodyAsString()

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.