Jak uzyskać treść odpowiedzi http jako ciąg w języku Java?


155

Wiem, że kiedyś istniał sposób na uzyskanie tego za pomocą apache commons, jak udokumentowano tutaj: http://hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpMethod.html i przykład tutaj:

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

ale uważam, że jest to przestarzałe. Czy istnieje inny sposób, aby żądanie HTTP get w java i uzyskać treść odpowiedzi jako ciąg znaków, a nie strumień?


1
Ponieważ pytanie i wszystkie odpowiedzi wydają się dotyczyć bibliotek Apache, należy to oznaczyć jako takie. Nie widzę niczego bez korzystania z bibliotek innych firm.
eis

Odpowiedzi:


104

Każda biblioteka, o której przychodzi mi do głowy, zwraca strumień. Możesz użyć IOUtils.toString()z Apache Commons IO do wczytania InputStreamdo Stringwywołania metody w jednym. Na przykład:

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

Aktualizacja: Zmieniłem powyższy przykład, aby użyć kodowania treści z odpowiedzi, jeśli jest dostępne. W przeciwnym razie najlepszym rozwiązaniem będzie domyślny kod UTF-8, zamiast używania domyślnego systemu lokalnego.


4
w wielu przypadkach spowoduje to uszkodzenie tekstu, ponieważ metoda wykorzystuje domyślne systemowe kodowanie tekstu, które różni się w zależności od systemu operacyjnego i ustawień użytkownika.
McDowell

1
@McDowell: oops dzięki, połączyłem javadoc dla metody z kodowaniem, ale zapomniałem go użyć w przykładzie. Dodałem na razie UTF-8 do przykładu, chociaż technicznie powinienem używać Content-Encodingnagłówka z odpowiedzi, jeśli jest dostępny.
WhiteFang 34

Świetne wykorzystanie IOUtils. Niezłe, praktyczne podejście.
Spidey

8
Właściwie charset jest określony w contentType, np. „Charset = ...”, ale nie w contentEncoding, który zawiera coś w rodzaju „gzip”
Timur Yusupov,

1
ta funkcja powoduje zamknięcie strumienia wejściowego, czy jest sposób, @ WhiteFang34, mogę wydrukować swoją odpowiedź i nadal używać encji http
amIT

274

Oto dwa przykłady z mojego projektu roboczego.

  1. Korzystanie EntityUtilsiHttpEntity

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

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

10
Jedynym problemem, z jakim miałem do czynienia w przypadku metody 1, jest to, że obiekt encji jest zużywany, gdy to robisz, response.getEntity()i jest teraz dostępny jako responseString. jeśli spróbujesz ponownie wykonać odpowiedź.getEntity (), to zwróci IllegalStateException.
Tirtha,

Zadziałało w moim przypadku - pobieranie treści z odpowiedzi CloseableHttpClient.
Jaroslav Štreit

1
Co to jest httpClient ?!
Andreas L.

1
@AndreasL. httpClient jest typu HttpClient (pakiet org.apache.commons.httpclient)
spishingweb

Często zdarza się, że zawartość odpowiedzi jest pobierana w postaci ciągu znaków, tablicy bajtów lub czegoś podobnego. Byłoby miło z interfejsem API bezpośrednio w Entity, aby to zapewnić. Konieczność szukania tego, aby znaleźć tę klasę użytkową.
Claus Ibsen

52

Oto przykład z innego prostego projektu, nad którym pracowałem, używając biblioteki httpclient z 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);
}

po prostu użyj EntityUtils, aby pobrać treść odpowiedzi jako String. bardzo prosty.


28

Jest to stosunkowo proste w konkretnym przypadku, ale dość trudne w przypadku ogólnym.

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

Odpowiedź zależy od Content-Type nagłówka odpowiedzi HTTP .

Ten nagłówek zawiera informacje o ładunku i może definiować kodowanie danych tekstowych. Nawet jeśli przyjmiesz typ tekstu , może być konieczne zbadanie samej treści w celu określenia prawidłowego kodowania znaków. Np. Zobacz specyfikację HTML 4, aby dowiedzieć się, jak to zrobić dla tego konkretnego formatu.

Gdy kodowanie jest znane, do dekodowania danych można użyć InputStreamReader .

Ta odpowiedź zależy od tego, czy serwer postąpi właściwie - jeśli chcesz obsłużyć przypadki, w których nagłówki odpowiedzi nie są zgodne z dokumentem lub deklaracje dokumentu nie pasują do zastosowanego kodowania, to kolejny kocioł ryb.


jak zdobyć to jako HashMap? Otrzymuję odpowiedź jako Json, jak to przeczytać?
user1735921

10

Poniżej znajduje się prosty sposób uzyskiwania dostępu do odpowiedzi jako ciągu znaków przy użyciu biblioteki klienta 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

A co powiesz na to?

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

9

Odpowiedź McDowella jest poprawna. Jeśli jednak spróbujesz innych sugestii w kilku z powyższych postów.

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

Wtedy otrzymasz wyjątek nielegalnyStateException stwierdzający, że zawartość jest już wykorzystana.


3

Możemy również użyć poniższego kodu, aby uzyskać odpowiedź HTML w 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);

    }
}

To bardzo dobra odpowiedź, to właśnie muszę wyświetlić, odpowiedź po przesłaniu danych na serwer. Dobra robota.
SlimenTN

0

Oto prosty sposób, aby to zrobić:

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

Oczywiście responseStringz odpowiedzią strony internetowej i typem odpowiedzi HttpResponsezwróconym przezHttpClient.execute(request)


0

Poniżej znajduje się fragment kodu, który pokazuje lepszy sposób obsługi treści odpowiedzi jako ciągu, niezależnie od tego, czy jest to poprawna odpowiedź, czy odpowiedź błędu dla żądania 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;
    }
}

0

Możesz użyć biblioteki innej firmy, która wysyła żądanie HTTP i obsługuje odpowiedź. Jednym z dobrze znanych produktów byłby Apache commons HTTPClient: HttpClient javadoc , HttpClient Maven artefact . Istnieje znacznie mniej znany, ale znacznie prostszy HTTPClient (część napisanej przeze mnie biblioteki MgntUtils typu open source): MgntUtils HttpClient javadoc , MgntUtils maven artefact , MgntUtils Github . Korzystając z jednej z tych bibliotek, możesz wysłać żądanie REST i otrzymać odpowiedź niezależnie od Springa w ramach logiki biznesowej


0

Jeśli używasz Jacksona do deserializacji treści odpowiedzi, jednym bardzo prostym rozwiązaniem jest użycie request.getResponseBodyAsStream()zamiastrequest.getResponseBodyAsString()

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.