Comment puis-je obtenir un corps de réponse http sous forme de chaîne en Java?

155

Je sais qu'il y avait un moyen de l'obtenir avec apache commons comme documenté ici: http://hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpMethod.html et un exemple ici:

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

mais je pense que c'est obsolète. Existe-t-il un autre moyen de faire une requête http get en java et d'obtenir le corps de la réponse sous forme de chaîne et non de flux?

Danois94
la source
1
Puisque la question et toutes les réponses semblent concerner les bibliothèques Apache, cela doit être étiqueté comme tel. Je ne vois rien sans utiliser les bibliothèques tierces.
eis

Réponses:

104

Chaque bibliothèque à laquelle je pense renvoie un flux. Vous pouvez utiliser IOUtils.toString()d' Apache Commons IO pour lire un InputStreamen un Stringdans un appel de méthode. Par exemple:

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

Mise à jour: j'ai changé l'exemple ci-dessus pour utiliser l'encodage du contenu de la réponse si disponible. Sinon, il sera par défaut UTF-8 comme meilleure estimation, au lieu d'utiliser la valeur par défaut du système local.

WhiteFang34
la source
4
cela corrompra le texte dans de nombreux cas car la méthode utilise le codage de texte par défaut du système qui varie en fonction du système d'exploitation et des paramètres utilisateur.
McDowell
1
@McDowell: oups merci, j'ai lié le javadoc pour la méthode avec l'encodage mais j'ai oublié de l'utiliser dans l'exemple. J'ai ajouté UTF-8 à l'exemple pour le moment, bien que techniquement, je devrais utiliser l'en- Content-Encodingtête de la réponse si disponible.
WhiteFang34
Grande utilisation des IOUtils. Belle approche pratique.
Spidey
8
En fait, charset est spécifié dans contentType comme "charset = ...", mais pas dans contentEncoding, qui contient quelque chose comme 'gzip'
Timur Yusupov
1
cette fonction provoque la fermeture du flux d'entrée, y a-t-il un moyen @ WhiteFang34 je peux imprimer ma réponse et continuer à utiliser l'entité http
amIT
275

Voici deux exemples de mon projet de travail.

  1. Utilisation EntityUtilsetHttpEntity

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

    HttpResponse response = httpClient.execute(new HttpGet(URL));
    String responseString = new BasicResponseHandler().handleResponse(response);
    System.out.println(responseString);
toile d'araignée
la source
10
Le seul problème que j'ai rencontré avec la méthode 1 est que l'objet entité est consommé lorsque vous le faites response.getEntity()et il est maintenant disponible en tant que responseString. si vous essayez de refaire un response.getEntity (), il reviendra IllegalStateException.
Tirtha
A fonctionné dans mon cas - obtenir le corps de la réponse CloseableHttpClient.
Jaroslav Štreit
1
Qu'est-ce que httpClient?!
Andreas L.
1
@AndreasL. httpClient est de type HttpClient (package org.apache.commons.httpclient)
spideringweb
Il est si courant d'obtenir le contenu de la réponse sous forme de chaîne ou de tableau d'octets ou quelque chose. Ce serait bien avec une API directement sur Entity pour vous donner cela. Devoir chercher ceci pour trouver cette classe util.
Claus Ibsen
52

Voici un exemple d'un autre projet simple sur lequel je travaillais en utilisant la bibliothèque httpclient d'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);
}

utilisez simplement EntityUtils pour saisir le corps de la réponse sous forme de chaîne. très simple.

fromage au clair de lune
la source
28

C'est relativement simple dans le cas particulier, mais assez délicat dans le cas général.

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 réponse dépend de l' Content-Type en-tête de la réponse HTTP .

Cet en-tête contient des informations sur la charge utile et peut définir le codage des données textuelles. Même si vous supposez des types de texte , vous devrez peut-être inspecter le contenu lui-même afin de déterminer le codage de caractères correct. Par exemple, consultez la spécification HTML 4 pour plus de détails sur la façon de procéder pour ce format particulier.

Une fois le codage connu, un InputStreamReader peut être utilisé pour décoder les données.

Cette réponse dépend du fait que le serveur fait la bonne chose - si vous voulez gérer les cas où les en-têtes de réponse ne correspondent pas au document, ou les déclarations de document ne correspondent pas au codage utilisé, c'est une autre marmite de poisson.

McDowell
la source
comment l'obtenir en tant que HashMap? Je reçois une réponse en tant que Json, comment lire cela?
user1735921
10

Vous trouverez ci-dessous un moyen simple d'accéder à la réponse sous forme de chaîne à l'aide de la bibliothèque 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);
lkamal
la source
9

Et pour ça?

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

La réponse de McDowell est correcte. Cependant, si vous essayez d'autres suggestions dans quelques-uns des articles ci-dessus.

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

Ensuite, il vous donnera illégaleStateException indiquant que le contenu est déjà consommé.

Akshay
la source
3

Nous pouvons également utiliser le code ci-dessous pour obtenir la réponse HTML en 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);

    }
}
Subhasish Sahu
la source
C'est une très bonne réponse, c'est ce que j'ai besoin d'afficher, la réponse après avoir posté des données sur le serveur. Bien joué.
SlimenTN
0

Voici un moyen léger de le faire:

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

Avec bien sûr responseStringla réponse et la réponse du site Web étant de type HttpResponse, renvoyées parHttpClient.execute(request)

Marko Zajc
la source
0

Voici l'extrait de code qui montre une meilleure façon de gérer le corps de la réponse sous forme de chaîne, qu'il s'agisse d'une réponse valide ou d'une réponse d'erreur pour la requête HTTP POST:

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
la source
0

Vous pouvez utiliser une bibliothèque tierce qui envoie une requête Http et gère la réponse. Un des produits les plus connus serait Apache commons HTTPClient: HttpClient javadoc , HttpClient Maven artifact . Il existe de loin moins connu mais beaucoup plus simple HTTPClient (qui fait partie d'une bibliothèque open source MgntUtils écrite par moi): MgntUtils HttpClient javadoc , MgntUtils maven artifact , MgntUtils Github . En utilisant l'une de ces bibliothèques, vous pouvez envoyer votre requête REST et recevoir une réponse indépendamment de Spring dans le cadre de votre logique métier

Michael Gantman
la source
0

Si vous utilisez Jackson pour désérialiser le corps de la réponse, une solution très simple consiste à utiliser request.getResponseBodyAsStream()au lieu derequest.getResponseBodyAsString()

Vic Seedoubleyew
la source