192

I know there used to be a way to get it with Apache Commons as documented here:

http://hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpMethod.html

...and an example here:

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

...but I believe this is deprecated.

Is there any other way to make an http get request in Java and get the response body as a string and not a stream?

Lii
  • 11,553
  • 8
  • 64
  • 88
Daniel Shaulov
  • 2,354
  • 2
  • 16
  • 25
  • 1
    Since the question and all the answers seem to be about apache libraries, this should be tagged as such. I don't see anything without using 3rdparty libs. – eis Jun 21 '16 at 15:19
  • related: https://stackoverflow.com/questions/21574478 – tkruse Mar 13 '20 at 02:29

13 Answers13

334

Here are two examples from my working project.

  1. Using EntityUtils and HttpEntity

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

    HttpResponse response = httpClient.execute(new HttpGet(URL));
    String responseString = new BasicResponseHandler().handleResponse(response);
    System.out.println(responseString);
    
Vadzim
  • 24,954
  • 11
  • 143
  • 151
spideringweb
  • 3,534
  • 2
  • 14
  • 17
  • 14
    The only problem I faced with method 1 is, the entity object is consumed when you do `response.getEntity()` and it is now available as `responseString`. if you try to do a response.getEntity() again, it'll return `IllegalStateException`. – Tirtha Jul 24 '13 at 06:42
  • Worked in my case - getting body from CloseableHttpClient response. – Jaroslav Štreit Oct 17 '16 at 10:53
  • 2
    What is httpClient?! – Andreas L. Jul 04 '17 at 11:48
  • 1
    @AndreasL. httpClient is of type HttpClient ( org.apache.commons.httpclient package) – spideringweb Jul 13 '17 at 19:38
  • 1
    Its so common to get the response content as string or byte array or something. Would be nice with an API directly on Entity to give you that. Having to look for this to find this util class. – Claus Ibsen Mar 25 '20 at 19:19
  • 1
    I upvoted. Please consider adding the full "imports" statements. – granadaCoder Jan 21 '21 at 19:32
  • Worth noting that the first method will get you the response body regardless of the HTTP status, whereas the second method throws exception for non-2xx HTTP statuses. – Jack Leow Oct 26 '21 at 13:30
  • How would you retrieve the response body for non-2xx HTTP statuses? – sm3sher Oct 28 '22 at 12:18
  • I am getting "Attempted read from closed stream." error while using body = EntityUtils.toString(response.getEntity()); – Prashant Singh Mar 16 '23 at 15:08
  • You should add how you've instantiated `httpClient` as its not necessarily clear to all readers – Sparm Jul 24 '23 at 10:42
119

Every library I can think of returns a stream. You could use IOUtils.toString() from Apache Commons IO to read an InputStream into a String in one method call. E.g.:

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: I changed the example above to use the content encoding from the response if available. Otherwise it'll default to UTF-8 as a best guess, instead of using the local system default.

WhiteFang34
  • 70,765
  • 18
  • 106
  • 111
  • 4
    this will corrupt text in many cases as the method uses the system default text encoding which varies based on OS and user settings. – McDowell Apr 24 '11 at 10:20
  • 1
    @McDowell: oops thanks, I linked the javadoc for the method with encoding but I forgot to use it in the example. I added UTF-8 to the example for now, although technically should use the `Content-Encoding` header from the response if available. – WhiteFang34 Apr 24 '11 at 10:30
  • Great usage of IOUtils. Nice pratical approach. – Spidey Jun 02 '11 at 05:50
  • 8
    Actually charset is specified in contentType like "charset=...", but not in contentEncoding, which contains something like 'gzip' – Timur Yusupov Feb 07 '12 at 14:17
  • Do I have to close the InputStream? –  Apr 17 '13 at 02:25
  • 1
    this function causes the input stream to be closed, is there a way @WhiteFang34 i can print my response and continue to use the http entity – amIT Mar 13 '15 at 11:25
  • this is link for apache commons https://mvnrepository.com/artifact/commons-io/commons-io/2.11.0 – dhanyn10 Jan 21 '23 at 15:51
53

Here's an example from another simple project I was working on using the httpclient library from 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);
}

just use EntityUtils to grab the response body as a String. very simple.

moonlightcheese
  • 10,664
  • 9
  • 49
  • 75
30

This is relatively simple in the specific case, but quite tricky in the general case.

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

The answer depends on the Content-Type HTTP response header.

This header contains information about the payload and might define the encoding of textual data. Even if you assume text types, you may need to inspect the content itself in order to determine the correct character encoding. E.g. see the HTML 4 spec for details on how to do that for that particular format.

Once the encoding is known, an InputStreamReader can be used to decode the data.

This answer depends on the server doing the right thing - if you want to handle cases where the response headers don't match the document, or the document declarations don't match the encoding used, that's another kettle of fish.

McDowell
  • 107,573
  • 31
  • 204
  • 267
11

Below is a simple way of accessing the response as a String using Apache HTTP Client library.

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
  • 3,788
  • 1
  • 20
  • 34
10

The Answer by McDowell is correct one. However if you try other suggestion in few of the posts above.

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

Then it will give you illegalStateException stating that content is already consumed.

Akshay
  • 806
  • 11
  • 26
9

How about just this?

org.apache.commons.io.IOUtils.toString(new URL("http://www.someurl.com/"));
jamesmortensen
  • 33,636
  • 11
  • 99
  • 120
Eric Schlenz
  • 2,551
  • 20
  • 19
3

We can use the below code also to get the HTML Response 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);

    }
}
Magnus
  • 17,157
  • 19
  • 104
  • 189
Subhasish Sahu
  • 1,297
  • 8
  • 9
  • This is a very good response, this is what I need to display, the response after posting data to the server. Well done. – SlimenTN Jan 01 '18 at 09:54
1

Here's a lightweight way to do so:

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

With of course responseString containing website's response and response being type of HttpResponse, returned by HttpClient.execute(request)

Marko Zajc
  • 307
  • 3
  • 14
1

Following is the code snippet which shows better way to handle the response body as a String whether it's a valid response or error response for the HTTP POST request:

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
  • 1,107
  • 13
  • 18
1

Here is a vanilla Java answer:

import java.net.http.HttpClient;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;

...
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
  .uri(targetUrl)
  .header("Content-Type", "application/json")
  .POST(BodyPublishers.ofString(requestBody))
  .build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
String responseString = (String) response.body();
William Entriken
  • 37,208
  • 23
  • 149
  • 195
0

If you are using Jackson to deserialize the response body, one very simple solution is to use request.getResponseBodyAsStream() instead of request.getResponseBodyAsString()

Vic Seedoubleyew
  • 9,888
  • 6
  • 55
  • 76
-1

Using Apache commons Fluent API, it can be done as mentioned below,

String response = Request.Post("http://www.example.com/")
                .body(new StringEntity(strbody))
                .addHeader("Accept","application/json")
                .addHeader("Content-Type","application/json")
                .execute().returnContent().asString();
pratap
  • 538
  • 1
  • 5
  • 11