0

I'm working on an intentservice that will do a httpget to a server and retrieve a json string.

I'm using the following code, which works aslong as the server is up:

 private String getServerContentsJson() throws IOException {
    HttpClient httpclient = new DefaultHttpClient();

   HttpResponse  response = httpclient.execute(new HttpGet(url));


    StatusLine statusline = response.getStatusLine();

    if(statusline.getStatusCode() == HttpStatus.SC_OK){

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        response.getEntity().writeTo(out);
        String responseString = out.toString();
        out.close();
        return responseString;}

    else{
        //Closes the connection.
        response.getEntity().getContent().close();
        throw new IOException(statusline.getReasonPhrase());

    }

The problem is when the server is down, I want to deal with that properly, but it is unclear to me how I can do this. According to the documentation httpclient.execute will either return a proper response, or throw IOException or ClientProtocolException, but instead I'm getting HttpHostConnectException: Connection to http://irrelevantURL refused which doesn't seem to trace back to my code. The app then crashes. Any suggestions?

Here's the full stack trace:

W/System.err﹕ org.apache.http.conn.HttpHostConnectException: Connection to http://irrelevantURL refused
W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:183)
W/System.err﹕ at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
W/System.err﹕ at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
W/System.err﹕ at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)

edit: I guess this isn't related to server being down, but instead it refuse connection for some reason, the question remains though I still want to deal with this properly so that the app does not crash

user2573715
  • 47
  • 1
  • 5

1 Answers1

2

HttpHostConnectException is a type of IOException, you are not handling it properly. You should have something like below. You probably do not want to throw a Exception if status_code is not 200, instead return a meaningful error responseString

  private String getServerContentsJson()
    throws IOException {
    HttpClient httpclient = new DefaultHttpClient();

    String responseString = null;
    HttpResponse response = null;
    try {
      response = httpclient.execute(new HttpGet(url));

      StatusLine statusline = response.getStatusLine();

      if (statusline.getStatusCode() == HttpStatus.SC_OK) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        response.getEntity().writeTo(out);
        responseString = out.toString();
        out.close();
        return responseString;
      } else {
        responseString = statusline.getReasonPhrase();
      }
    } catch (IOException e) {
      throw new IOException(e.getMessage(), e);
      //OR:
      //responseString = "Could not reach server, please try again";
    } finally {
      if (response != null) {
        response.getEntity().consumeContent();
      }
    }
    return responseString;
  }
vsnyc
  • 2,117
  • 22
  • 35
  • Hi thanks for the answer, I think I got it working now, however using your example here I get an exception for content already consumed in the finally block. I read some in the documentation, and replaced response.getEntity().getContent().close(); with response.getEntity().consumeContent(); which works, but also just commenting the whole line works so I guess the issue here is if this frees all the resources? – user2573715 Mar 25 '15 at 12:25
  • 1
    You are right, see [this answer](http://stackoverflow.com/questions/4775618/httpclient-4-0-1-how-to-release-connection/9498708#9498708). I have updated the code. Also, as suggested there, `EntityUtils.consume(response.getEntity()); ` might work as well and be the preferred way. Drop an update if you test it and I'll update the code – vsnyc Mar 25 '15 at 13:24