java.io.IOException: Attempted read from closed stream

Pra*_*tik 14 java jackson apache-httpclient-4.x

I am making a HTTPPost call using Apache HTTP Client and then I am trying to create an object from the response using Jackson. Here is my code:

private static final Logger log = Logger.getLogger(ReportingAPICall.class);
ObjectMapper mapper = new ObjectMapper();

public void makePublisherApiCall(String jsonRequest)
{
    String url = ReaderUtility.readPropertyFile().getProperty("hosturl");
    DefaultHttpClient client = new DefaultHttpClient();
    try {
        HttpPost postRequest = new HttpPost(url);
        StringEntity entity = new StringEntity(jsonRequest);
        postRequest.addHeader("content-type", "application/json");
        log.info("pub id :"+ExcelReader.publisherId);
        postRequest.addHeader("accountId", ExcelReader.publisherId);
        postRequest.setEntity(entity);
        HttpResponse postResponse = client.execute(postRequest);
        log.info(EntityUtils.toString(postResponse.getEntity()));

    //  Response<PublisherReportResponse> response = mapper.readValue(postResponse.getEntity().getContent(), Response.class);
    //  log.info("Reponse "+response.toString());
    } catch (UnsupportedEncodingException ex) {
        log.error(ex.getMessage());
        log.error(ex);
        Assert.assertTrue(false, "Exception : UnsupportedEncodingException");
    } catch (ClientProtocolException ex) {
        log.error(ex.getMessage());
        log.error(ex);
        Assert.assertTrue(false, "Exception : ClientProtocolException");
    } catch (IOException ex) {
        log.error(ex.getMessage());
        log.error(ex);
        Assert.assertTrue(false, "Exception : IOException");
    }
Run Code Online (Sandbox Code Playgroud)

Method makePublisherApiCall() will be called in a loop which runs for say 100 times. Basically problem occurs when I uncomment the line:

//  Response<PublisherReportResponse> response = mapper.readValue(postResponse.getEntity().getContent(), Response.class);
//  log.info("Reponse "+response.toString());
Run Code Online (Sandbox Code Playgroud)

After uncommenting I am getting exception:

Attempted read from closed stream.
17:26:59,384 ERROR com.inmobi.reporting.automation.reportingmanager.ReportingAPICall - java.io.IOException: Attempted read from closed stream.
Run Code Online (Sandbox Code Playgroud)

Otherwise it works fine. Could someone please let me know what I am doing wrong.

Pyr*_*nja 39

什么是EntityUtils.toString(postResponse.getEntity())与响应实体呢?我怀疑它正在消耗实体的内容流.该HttpClient的javadoc的状态,只有实体,这是重复的,可以食用超过一次.因此,如果实体不可重复,则无法再次将内容流提供给映射器.为避免这种情况,您应该只让映射器使用流 - 如果需要记录内容,请记录已解析的Response对象.

  • 当然可以.如果我是正确的,问题是你只能**消耗一次实体的内容.我怀疑你是通过日志记录然后进行解析两次.如果你想检查我的怀疑是否正确,请注释掉`log.info(EntityUtils.toString(postResponse.getEntity()));并取消注释以下两行,然后再次检查它是否有效. (2认同)

小智 8

我在这里找到了 Spring RestTemplate 类似问题的答案:https ://www.baeldung.com/spring-rest-template-interceptor

如果我们希望我们的拦截器充当请求/响应记录器,那么我们需要读取它两次——第一次由拦截器读取,第二次由客户端读取。默认实现只允许我们读取响应流一次。为了迎合这样的特定场景,Spring 提供了一个名为 BufferingClientHttpRequestFactory 的特殊类。顾名思义,此类将在 JVM 内存中缓冲请求/响应以供多次使用。

以下是使用 BufferingClientHttpRequestFactory 初始化 RestTemplate 对象以启用请求/响应流缓存的方法:

RestTemplate restTemplate = new RestTemplate( new BufferingClientHttpRequestFactory( new SimpleClientHttpRequestFactory() ) );
Run Code Online (Sandbox Code Playgroud)


aug*_*490 5

我有同样的问题。确保您没有在IDE的“监视”或“检查”部分中使用实体的内容流。它被消耗(读取)后关闭。

对不起,我的英语。