Bir http yanıt gövdesini Java'da dize olarak nasıl alabilirim?


155

Burada belgelendiği gibi apache commons ile almanın bir yolu olduğunu biliyorum: http://hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpMethod.html ve burada bir örnek:

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

ama bunun onaylanmadığına inanıyorum. Java'da bir http alma isteği yapmanın ve yanıt gövdesini bir dize olarak değil, bir dize olarak almanın başka bir yolu var mı?


1
Soru ve tüm cevaplar apache kütüphaneleri ile ilgili göründüğü için, bu şekilde etiketlenmelidir. Üçüncü taraf kütüphanelerini kullanmadan hiçbir şey görmüyorum.
eis

Yanıtlar:


104

Aklıma gelen her kütüphane bir akış döndürüyor. Sen kullanabilirsiniz IOUtils.toString()gelen Apache Commons IO bir okumaya InputStreambir içine Stringbir yöntem çağrısında. Örneğin:

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

Güncelleme: Varsa yanıttan içerik kodlamasını kullanmak için yukarıdaki örneği değiştirdim. Aksi takdirde, yerel sistem varsayılanını kullanmak yerine varsayılan olarak en iyi tahmin olarak UTF-8 olacaktır.


4
yöntem, işletim sistemi ve kullanıcı ayarlarına göre değişen sistem varsayılan metin kodlamasını kullandığından, çoğu durumda metni bozar.
McDowell

1
@McDowell: ayy teşekkürler, yöntem için javadoc kodlama ile bağladım ama örnekte kullanmayı unuttum. Şimdilik örneğe UTF-8 ekledim, ancak teknik olarakContent-Encoding varsa yanıttaki başlığı .
WhiteFang34

IOUtils'in büyük kullanımı. Güzel pratik yaklaşım.
Spidey

8
Aslında karakter kümesi, "charset = ..." gibi contentType'ta belirtilir, ancak "gzip" gibi bir şey içeren contentEncoding içinde belirtilmez
Timur Yusupov

1
Bu işlev giriş akışının kapatılmasına neden olur, @ WhiteFang34 yanıtımı yazdırabilir ve http
objesini

276

İşte benim çalışma projemden iki örnek.

  1. kullanılması EntityUtilsveHttpEntity

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

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

10
Yöntem 1 ile karşı karşıya olduğum tek sorun, varlık nesnesi yaptığınızda tüketilir response.getEntity()ve artık kullanılabilir responseString. tekrar bir response.getEntity () yapmaya çalışırsanız, geri dönecektir IllegalStateException.
Tirtha

Benim durumumda çalıştı - CloseableHttpClient yanıt vücut almak.
Jaroslav Štreit

1
HttpClient nedir ?!
Andreas L.

1
@AndreasL. httpClient, HttpClient türündedir (org.apache.commons.httpclient paket)
spideringweb

Yanıt içeriğini dize veya bayt dizisi veya başka bir şey olarak almak çok yaygındır. Bunu vermek için doğrudan Entity üzerinde bir API ile iyi olurdu. Bu util sınıfını bulmak için bunu aramak zorunda.
Claus Ibsen

52

Apache'nin httpclient kütüphanesini kullanarak üzerinde çalıştığım başka bir basit projeden bir örnek:

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

yanıt gövdesini bir String olarak almak için EntityUtils kullanın. Çok basit.


28

Bu, spesifik durumda nispeten basittir, ancak genel durumda oldukça zordur.

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

Yanıt, Content-Type HTTP yanıt başlığına bağlıdır .

Bu başlık yükü hakkında bilgi içerir ve olabilir metinsel veri kodlama tanımlar. Metin türlerini varsaysanız bile , doğru karakter kodlamasını belirlemek için içeriğin kendisini incelemeniz gerekebilir. Örneğin , belirli bir biçim için bunun nasıl yapılacağıyla ilgili ayrıntılar için HTML 4 spesifikasyonuna bakın.

Kodlama bilindikten sonra, verilerin kodunu çözmek için bir InputStreamReader kullanılabilir.

Bu yanıt, sunucunun doğru şeyi yapmasına bağlıdır - yanıt başlıklarının belgeyle eşleşmediği veya belge bildirimlerinin kullanılan kodlamayla eşleşmediği durumları ele almak istiyorsanız, bu başka bir balık su ısıtıcısıdır.


HashMap olarak nasıl alabilirim? Json olarak cevap alıyorum, nasıl okunur?
user1735921

10

Aşağıda, Apache HTTP İstemcisi kitaplığını kullanarak yanıta Dize olarak erişmenin basit bir yolu verilmiştir.

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

Buna ne dersin?

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

9

McDowell'in Cevabı doğrudur. Ancak yukarıdaki gönderilerin birkaçında başka bir öneri denerseniz.

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

Ardından, içeriğin zaten tüketildiğini belirten illegalStateException değerini verir.


3

Java'da HTML Yanıtı almak için aşağıdaki kodu da kullanabiliriz

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

    }
}

Bu çok iyi bir yanıt, bu benim görüntülemek gerekenler, sunucuya veri gönderdikten sonra yanıt. Aferin.
2018'de

0

İşte bunu yapmanın hafif bir yolu:

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

Tabii ki responseStringweb sitesinin yanıtı ve yanıtı türünü içeren HttpResponse, tarafından döndürülenHttpClient.execute(request)


0

HTTP POST isteği için geçerli bir yanıt veya hata yanıtı olsun yanıt gövdesini Dize olarak ele almanın daha iyi bir yolunu gösteren kod snippet'i aşağıdadır:

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

Http isteği gönderen ve yanıtı işleyen 3 boyutlu bir parti kitaplığı kullanabilirsiniz. Bilinen ürünlerden biri Apache ortak HTTPClient olacaktır: HttpClient javadoc , HttpClient Maven artefaktı . Çok daha az bilinen ama çok daha basit HTTPClient (benim tarafımdan yazılmış bir açık kaynak MgntUtils kütüphanesinin parçası): MgntUtils HttpClient javadoc , MgntUtils maven artefaktı , MgntUtils Github . Bu kitaplıklardan birini kullanarak REST isteğinizi gönderebilir ve iş mantığınızın bir parçası olarak İlkbahar'dan bağımsız olarak yanıt alabilirsiniz


0

Yanıt gövdesini serileştirmek için Jackson kullanıyorsanız, request.getResponseBodyAsStream()bunun yerine çok basit bir çözüm kullanmaktır .request.getResponseBodyAsString()

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.