IllegalStateException: Content has been consumed

来源:互联网 发布:db2 sql查询取第一条 编辑:程序博客网 时间:2024/05/17 03:45
其实翻过过来核心就是说HTTPRESPONSE对象在返回的时候,只能被取值一次!
当去过一次值之后再取值,就会报这个错误!

IllegalStateException: Content has been consumed

When working with Android or (to be more general) Apache HttpComponents, one 

should keep in mind that it depends on the HttpResponses (Api: Apache, Android) if 

they can be consumed multiple times or not. And if the response is not, then 

better triple check your code, what you’re doing.

I experiences the (very ugly) issue during the apparently simple task of reading 

the content of the response. )For ease of simplicity, I also use Apache commons-

io, to read buffers etc.)

1
2
HttpResponse response = ...;
String content = IOUtils.toString(response.getEntity().entity.getContent());
Okay, how many possible Nullpointer Exceptions do you see? I didn’t care until I experienced the first one, so I made the code NPE safe:

1
2
3
4
5
6
7
8
9
HttpEntity entity = response.getEntity();
// entity can be null according to the docs!
if (entity != null) { 
    // The interface doesn't say that getContent() MUST return non-null
    InputStream stream = entity.getContent(); 
        if (stream != null) {
            tempContent = IOUtils.toString(entity.getContent());
        }
}
And suddenly I was faced with IllegalStateException: Content has been consumed. As 

I also did changes somewhere else, I assumed the error in some toString()-Methods 

that would read the content of the response during debugging. But as the error 

also showed up without debugging, I had a closer look to my “improvement”.

Well, the error was the call IOUtils.toString(entity.getContent()); which tried to 

re-aquire the Input Stream. But as I just aquired it two lines above for the null 

check, the content was already marked as consumed. So the (now hopefully) correct 

and robust code is:

1
2
3
4
5
6
7
8
9
HttpEntity entity = response.getEntity();
// entity can be null according to the docs!
if (entity != null) { 
    // The interface doesn't say that getContent() MUST return non-null
    InputStream stream = entity.getContent(); 
        if (stream != null) {
            tempContent = IOUtils.toString(<strong>stream</strong>);
        }
}
And the moral of the story

Be very carefull when reading HttpResponses! Also avoid pretty-printing the 

content in toString() – this might suddenly also consume your content. And good 

luck finding the point where you consume the content in such cases.

But .. why?! Please avoid returning null!

Yet I still wonder, why so many methods are allowed to return null instead of just 

an empty stream or something. All the Null-checks don’t make the code more 

readable. Some programmers might even be tempted to simply put an catch

(NullPointerException e) around the part of

1
response.getEntity().entity.getContent()
. Nothing I’d really recommend but I could also understand if I’d see something 

in other code.
0 0