使用 HttpRequest.execute() 时出现异常:SingleClientConnManager 的使用无效:连接仍然分配
我正在使用 google-api-client-java 1.2.1-alpha 执行 POST 请求,并且当我执行() HttpRequest 时得到以下堆栈跟踪。
在我捕获并忽略上一个 POST 到同一 URL 的 403 错误并重新使用后续请求的传输后,就会立即发生这种情况。 (它在一个循环中将多个条目插入到同一个 ATOM feed 中)。
出现 403 错误后我应该做些什么来“清理”吗?
Exception in thread "main" java.lang.IllegalStateException: Invalid use of SingleClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.
at org.apache.http.impl.conn.SingleClientConnManager.getConnection(SingleClientConnManager.java:199)
at org.apache.http.impl.conn.SingleClientConnManager$1.getConnection(SingleClientConnManager.java:173)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:390)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
at com.google.api.client.apache.ApacheHttpRequest.execute(ApacheHttpRequest.java:47)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:207)
at au.com.machaira.pss.gape.RedirectHandler.execute(RedirectHandler.java:38)
at au.com.machaira.pss.gape.ss.model.records.TableEntry.executeModification(TableEntry.java:81)
为什么我下面的代码会尝试获取新连接?
I'm using google-api-client-java 1.2.1-alpha to execute a POST request, and am getting the following stacktrace when I execute() the HttpRequest.
It happens immediately after I catch and ignore a 403 error from a previous POST to the same URL, and re-used the transport for the subsequent request. (It's in a loop inserting multiple entries to the same ATOM feed).
Is there something I should be doing to 'clean up' after a 403?
Exception in thread "main" java.lang.IllegalStateException: Invalid use of SingleClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.
at org.apache.http.impl.conn.SingleClientConnManager.getConnection(SingleClientConnManager.java:199)
at org.apache.http.impl.conn.SingleClientConnManager$1.getConnection(SingleClientConnManager.java:173)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:390)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
at com.google.api.client.apache.ApacheHttpRequest.execute(ApacheHttpRequest.java:47)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:207)
at au.com.machaira.pss.gape.RedirectHandler.execute(RedirectHandler.java:38)
at au.com.machaira.pss.gape.ss.model.records.TableEntry.executeModification(TableEntry.java:81)
Why would the code below me be trying to acquire a new connection?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
您需要先使用响应正文,然后才能将连接重用于另一个请求。您不仅应该读取响应状态,还应该完全读取响应
InputStream
直到最后一个字节,从而忽略读取的字节。You need to consume the response body before you can reuse the connection for another request. You should not only read the response status, but read the response
InputStream
fully to the last byte whereby you just ignore the read bytes.在使用 HttpClient 和 Jetty 构建测试框架时,我遇到了类似的问题。我必须从客户端创建多个对 Servlet 的请求,但在执行时它给出了相同的异常。
我在 http://foo.jasonhudgins.com/2010/ 找到了替代方案03/http-connections-revisited.html
您还可以使用以下方法来实例化您的客户端。
I was facing a similar issue when using the HttpClient with Jetty to build a test framework. I had to create multiple requests to the Servelet from my client, but It was giving the same exception when executed.
I found an alternative at http://foo.jasonhudgins.com/2010/03/http-connections-revisited.html
You can also use this following method to instantiate your client.
类似的异常消息(至少从 Apache Jarkata Commons HTTP Client 4.2 起)是:
java.lang.IllegalStateException:BasicClientConnManager 的使用无效:连接仍在分配。
确保在分配另一个连接之前释放连接。
当两个或多个线程与单个 org.apache.http.impl.client.DefaultHttpClient 交互时,可能会发生此异常。
如何使 4.2
DefaultHttpClient
实例线程安全(线程安全是指两个或多个线程可以与其交互而不会收到上述错误消息)?以org.apache.http.impl.conn.PoolingClientConnectionManager
的形式为DefaultHttpClient
提供连接池ClientConnectionManager
!A similar exception message (since at least Apache Jarkata Commons HTTP Client 4.2) is:
java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.
This exception can happen when two or more threads interact with a single
org.apache.http.impl.client.DefaultHttpClient
.How can you make a 4.2
DefaultHttpClient
instance threadsafe (threadsafe in the sense that two or more threads can interact with it without getting above error message)? ProvideDefaultHttpClient
with a connection-poolingClientConnectionManager
in the form oforg.apache.http.impl.conn.PoolingClientConnectionManager
!这是一个经常被问到的问题。 BalusC的回应是正确的。请抓住 HttpReponseException,并调用 HttpResponseException。响应。忽略()。如果您需要阅读错误消息,请使用response。parseAsString() 如果您不知道响应内容类型,否则如果您知道内容类型,请使用响应。parseAs(MyType.class)。
来自 YouTubeSample.java /youtube-jsonc-sample/instructions.html?r=default" rel="noreferrer">youtube-jsonc-sample (尽管通常您会希望在实际应用程序中做一些更聪明的事情):
完全披露:我是 google-api-java-client 项目的所有者。
This is an often-asked question. BalusC's response is correct. Please catch HttpReponseException, and call HttpResponseException.response.ignore(). If you need to read the error message, use response.parseAsString() if you don't know the response content type, else if you do know the content type use response.parseAs(MyType.class).
A simple code snippet from YouTubeSample.java in youtube-jsonc-sample (though usually you'll want to do something smarter in a real application):
Full disclosure: I am an owner of the google-api-java-client project.
我在单元测试中使用 jax-rs (resteasy)
Response
对象也遇到了同样的问题。我通过调用response.releaseConnection();解决了这个问题
releaseConnection() 方法仅适用于 Resteasy
ClientResponse
对象,因此我必须添加从Response
到ClientResponse
的转换。I had the same issue with a jax-rs (resteasy)
Response
object in my unit tests.I solved this with a call to
response.releaseConnection();
The releaseConnection()-Method is only on the resteasy
ClientResponse
object, so I had to add a cast fromResponse
toClientResponse
.试试这个
Try this
好的,我有类似的问题,所有这些解决方案都不起作用,我在某些设备上进行了测试,问题是设备中的日期,它是 2011 年而不是 2013 年,检查一下这也可以提供帮助。
Ok, i have similar problem, all those solution not work, i tested on some device, problem was date in device, it was 2011 instead 2013, check also this can help.
像这样读取输入流:
Read the InputStream like this:
只需使用如下所示的响应即可解决问题
just consume the response like below, that will solve the issue