Dav*_*ock 80 java httpclient google-api-java-client
我正在使用google-api-client-java 1.2.1-alpha来执行POST请求,并在执行()HttpRequest时获得以下stacktrace.
它在我捕获并忽略从先前的POST到同一URL的403错误后立即发生,并重新使用传输进行后续请求.(它在一个循环中插入多个条目到同一个ATOM提要).
在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)
Run Code Online (Sandbox Code Playgroud)
为什么我下面的代码会尝试获取新连接?
Bal*_*usC 80
在为另一个请求重用连接之前,您需要使用响应主体.您不仅应该读取响应状态,还应该完全读取InputStream最后一个字节的响应,从而忽略读取的字节.
Ujj*_*wan 42
在使用HttpClient和Jetty构建测试框架时,我遇到了类似的问题.我不得不从我的客户端向Servelet创建多个请求,但它在执行时给出了相同的异常.
我在http://foo.jasonhudgins.com/2010/03/http-connections-revisited.html找到了另一种选择.
您还可以使用以下方法来实例化您的客户端.
public static DefaultHttpClient getThreadSafeClient() {
DefaultHttpClient client = new DefaultHttpClient();
ClientConnectionManager mgr = client.getConnectionManager();
HttpParams params = client.getParams();
client = new DefaultHttpClient(new ThreadSafeClientConnManager(params,
mgr.getSchemeRegistry()), params);
return client;
}
Run Code Online (Sandbox Code Playgroud)
类似的异常消息(至少Apache Jarkata Commons HTTP Client 4.2)是:
java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.
当两个或多个线程与单个线程交互时,可能会发生此异常org.apache.http.impl.client.DefaultHttpClient.
你如何制作一个4.2 DefaultHttpClient实例线程安全(线程安全,因为两个或多个线程可以与它交互而不会得到上面的错误消息)?DefaultHttpClient以ClientConnectionManager形式提供连接池org.apache.http.impl.conn.PoolingClientConnectionManager!
/* using
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.2</version>
</dependency>
*/
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.impl.conn.SchemeRegistryFactory;
import org.apache.http.params.HttpParams;
import org.apache.http.client.methods.HttpGet;
public class MyComponent {
private HttpClient client;
{
PoolingClientConnectionManager conMan = new PoolingClientConnectionManager( SchemeRegistryFactory.createDefault() );
conMan.setMaxTotal(200);
conMan.setDefaultMaxPerRoute(200);
client = new DefaultHttpClient(conMan);
//The following parameter configurations are not
//neccessary for this example, but they show how
//to further tweak the HttpClient
HttpParams params = client.getParams();
HttpConnectionParams.setConnectionTimeout(params, 20000);
HttpConnectionParams.setSoTimeout(params, 15000);
}
//This method can be called concurrently by several threads
private InputStream getResource(String uri) {
try {
HttpGet method = new HttpGet(uri);
HttpResponse httpResponse = client.execute(method);
int statusCode = httpResponse.getStatusLine().getStatusCode();
InputStream is = null;
if (HttpStatus.SC_OK == statusCode) {
logger.debug("200 OK Amazon request");
is = httpResponse.getEntity().getContent();
} else {
logger.debug("Something went wrong, statusCode is {}",
statusCode);
EntityUtils.consume(httpResponse.getEntity());
}
return is;
} catch (Exception e) {
logger.error("Something went terribly wrong", e);
throw new RuntimeException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个经常被问到的问题.BalusC的回答是正确的.请捕获HttpReponseException,并调用HttpResponseException.回应.ignore().如果需要阅读错误消息,请使用响应.如果您不知道响应内容类型,则为parseAsString(),否则,如果您确实知道内容类型使用响应.parseAs(MyType.class).
从一个简单的代码片断YouTubeSample.java在YouTube上jsonc样本(尽管通常你会想要做的事聪明在实际应用中):
} catch (HttpResponseException e) {
System.err.println(e.response.parseAsString());
}
Run Code Online (Sandbox Code Playgroud)
完全披露:我是google-api-java-client项目的所有者.