[英]JAVA Using IOUtils.toString with HttpEntity.getContent() converting the InputStream to null
我有一個奇怪的senario我有HTTP響應,我嘗試將其轉換為字符串,問題是第一次運行,但第二次InputStream數據為null
而且我只在response1中有數據
InputStream is = entity.getContent();
String response1 = IOUtils.toString(is, "utf-8"); // Here every thing is fine
String respons2 = IOUtils.toString(is, "utf-8"); // Here the response2 is empty
and is (InputStream) holding no data
這是什么問題,我需要能夠將數據保存在InputStream中,以備將來在代碼中使用
但是,當檢查javadoc httpEntity.getContent時,您的需求不是很清楚:
返回實體的內容流。 每次此方法的調用,可重復的實體都將創建一個InputStream的新實例,因此可以多次使用。 不可重復的實體應返回相同的InputStream實例,因此消耗的次數不得超過一次。
您是否通過調用檢查httpEntity是否可重復
httpEntity.isRepeatable()
如果為true,則可以執行以下操作:
InputStream is = entity.getContent();
String response1 = IOUtils.toString(is, "utf-8");
// retrieve a new instance of inputStream
is = entity.getContent();
String response2 = IOUtils.toString(is, "utf-8");
最后但並非最不重要的一點(因為我不知道您的確切需求),如果實體能夠多次產生其數據,那么前面的代碼會有所幫助,但是您應該評估以下兩者之間的成本:
不,流不應該被多次讀取。
如果您想保留流的內容以供重復使用,則可以這樣做。 在您的情況下,只需重新使用response1字符串即可。
在閱讀之前,您應該檢查流是否支持重置。 您可以檢查InputStream#markSupported()
的結果,該結果告訴您是否可以使用方法對mark()/reset()
。
如果支持mark,則可以在讀取時執行mark()
,然后reset()
返回開始。
如果httpEntity是不可重復的,則可以將InputStream包裹在BufferedInputStream中;否則,可以將InputStream包裝為BufferedInputStream。 這樣,您可以將其重置以允許重新讀取。 本質上,BufferedInputStream第一次將數據讀取到內部緩沖區中,然后在您重新讀取時重新使用該緩沖區。
final int bufferSize = 1_000_000; // about 1 MB; must be large enough to hold all the http content
InputStream is = new BufferedInputStream(entity.getContent(), bufferSize);
is.mark(bufferSize);
String response1 = IOUtils.toString(is, "utf-8");
is.reset();
String respons2 = IOUtils.toString(is, "utf-8");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.