Search code examples
javahttpclient

Stream closed when using http client


When using httpclient to get a response I get an error on line out.write(EntityUtils.toString(resEntity)); // it is line 70 in java code

Why is this happens?

    CloseableHttpClient httpClient = HttpClients.custom().setUserAgent("Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0").build();
    HttpResponse response = httpClient.execute(new HttpGet(searchLink.toString()));  
    HttpEntity resEntity = response.getEntity();
    System.out.println(EntityUtils.toString(resEntity));
    PrintWriter out = new PrintWriter(new File("searchResult.xml"));
    out.write(EntityUtils.toString(resEntity));
    out.flush();
    out.close();
    httpClient.close();

The error is

2015/08/07 13:03:12,887 ERROR [stderr] (Thread-101) java.io.IOException: Stream closed
2015/08/07 13:03:12,887 ERROR [stderr] (Thread-101)     at java.util.zip.GZIPInputStream.ensureOpen(GZIPInputStream.java:61)
2015/08/07 13:03:12,887 ERROR [stderr] (Thread-101)     at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:112)
2015/08/07 13:03:12,887 ERROR [stderr] (Thread-101)     at org.apache.http.client.entity.LazyDecompressingInputStream.read(LazyDecompressingInputStream.java:74)
2015/08/07 13:03:12,887 ERROR [stderr] (Thread-101)     at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
2015/08/07 13:03:12,887 ERROR [stderr] (Thread-101)     at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
2015/08/07 13:03:12,887 ERROR [stderr] (Thread-101)     at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
2015/08/07 13:03:12,887 ERROR [stderr] (Thread-101)     at java.io.InputStreamReader.read(InputStreamReader.java:184)
2015/08/07 13:03:12,888 ERROR [stderr] (Thread-101)     at java.io.Reader.read(Reader.java:140)
2015/08/07 13:03:12,888 ERROR [stderr] (Thread-101)     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:244)
2015/08/07 13:03:12,888 ERROR [stderr] (Thread-101)     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:288)
2015/08/07 13:03:12,888 ERROR [stderr] (Thread-101)     at mainThread.Search.doRequest(Search.java:70)
2015/08/07 13:03:12,888 ERROR [stderr] (Thread-101)     at mainThread.Search.search(Search.java:29)
...

At the same time the response from request is successfully recieved on line

System.out.println(EntityUtils.toString(resEntity));

Solution

  • You can't read the response stream twice, which is what you are doing by effectively invoking EntityUtils.toString(resEntity) twice.

    System.out.println(EntityUtils.toString(resEntity)); // once
    // ...
    out.write(EntityUtils.toString(resEntity)); // twice
    

    By the time you get to the 2nd time, the response stream has no more data to read.

    In this case, just make sure you read the response stream once by assigning the resulting string to a variable. You can then safely use that string variable as many times as you like.

    String resEntityToString = EntityUtils.toString(resEntity);
    System.out.println(resEntityToString);
    // ...
    out.write(resEntityToString);