首页 > 代码库 > 解决Get content and status code from HttpResponse问题
解决Get content and status code from HttpResponse问题
在调用 apache的http处理jar包的时候,我们可能遇到过先判断返回的响应的状态是否正确,然后取值,这个时候就会在returnContent()的时候报异常
java.lang.IllegalStateException: Response content has been already consumed at org.apache.http.client.fluent.Response.assertNotConsumed(Response.java:56) at org.apache.http.client.fluent.Response.handleResponse(Response.java:88) at org.apache.http.client.fluent.Response.returnContent(Response.java:97)
原因:
在returnResponse()的finally中会把全局变量consumed置为true,returnContent()调用handleResponse中调用了dispose,dispose最后的finally中也将全局变量consumed置为true,而assertNotConsumed()是consumed为true就抛异常的,所以无论先调用哪一个都会出现异常。
public HttpResponse returnResponse() throws IOException { assertNotConsumed(); try { final HttpEntity entity = this.response.getEntity(); if (entity != null) { final ByteArrayEntity byteArrayEntity = new ByteArrayEntity( EntityUtils.toByteArray(entity)); final ContentType contentType = ContentType.getOrDefault(entity); byteArrayEntity.setContentType(contentType.toString()); this.response.setEntity(byteArrayEntity); } return this.response; } finally { this.consumed = true; } }
public Content returnContent() throws ClientProtocolException, IOException { return handleResponse(new ContentResponseHandler()); } /** * Handles the response using the specified {@link ResponseHandler} */ public <T> T handleResponse( final ResponseHandler<T> handler) throws ClientProtocolException, IOException { assertNotConsumed(); try { return handler.handleResponse(this.response); } finally { dispose(); } } private void dispose() { if (this.consumed) { return; } try { final HttpEntity entity = this.response.getEntity(); final InputStream content = entity.getContent(); if (content != null) { content.close(); } } catch (final Exception ignore) { } finally { this.consumed = true; } }
private void assertNotConsumed() { if (this.consumed) { throw new IllegalStateException("Response content has been already consumed"); } }
解决办法:
在returnContent()中,先对Response的状态进行判断,状态值大于300的,会抛出对应的异常,然后调用EntityUtils.toString(entity)取值,所以可以先取HttpResponse,然后用
byte[] bytes = EntityUtils.toByteArray(httpResponse.getEntity());来取Content.
public Content returnContent() throws ClientProtocolException, IOException { return handleResponse(new ContentResponseHandler()); } public <T> T handleResponse( final ResponseHandler<T> handler) throws ClientProtocolException, IOException { assertNotConsumed(); try { return handler.handleResponse(this.response); } finally { dispose(); } } public T handleResponse(final HttpResponse response) throws HttpResponseException, IOException { final StatusLine statusLine = response.getStatusLine(); final HttpEntity entity = response.getEntity(); if (statusLine.getStatusCode() >= 300) { EntityUtils.consume(entity); throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); } return entity == null ? null : handleEntity(entity); } @Override public String handleEntity(final HttpEntity entity) throws IOException { return EntityUtils.toString(entity); }
解决Get content and status code from HttpResponse问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。