[英]Java HTTP Client Request with defined timeout
我想在我的云中为多个服务器制作BIT(内置测试)。 我需要请求在大超时时失败。
我应该如何用java做到这一点?
尝试类似下面的东西似乎不起作用。
public class TestNodeAliveness {
public static NodeStatus nodeBIT(String elasticIP) throws ClientProtocolException, IOException {
HttpClient client = new DefaultHttpClient();
client.getParams().setIntParameter("http.connection.timeout", 1);
HttpUriRequest request = new HttpGet("http://192.168.20.43");
HttpResponse response = client.execute(request);
System.out.println(response.toString());
return null;
}
public static void main(String[] args) throws ClientProtocolException, IOException {
nodeBIT("");
}
}
- 编辑:澄清正在使用的库 -
我正在使用apache的httpclient,这是相关的pom.xml部分
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<type>jar</type>
</dependency>
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
...
// set the connection timeout value to 30 seconds (30000 milliseconds)
final HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
client = new DefaultHttpClient(httpParams);
如果您使用的是Http Client 4.3及以上版本,那么您应该使用:
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
HttpParams在新的Apache HTTPClient库中已弃用。 使用Laz提供的代码会导致弃用警告。
我建议在你的HttpGet或HttpPost实例上使用RequestConfig:
final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();
httpPost.setConfig(params);
看起来您正在使用HttpClient API,我对此一无所知,但您可以使用核心Java编写类似的内容。
try {
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("HEAD");
con.setConnectTimeout(5000); //set timeout to 5 seconds
return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
} catch (java.net.SocketTimeoutException e) {
return false;
} catch (java.io.IOException e) {
return false;
}
我发现在HttpConnectionParams
和HttpConnectionManager
设置超时设置并没有解决我们的问题。 我们仅限于使用org.apache.commons.httpclient
3.0.1版。
我最终使用java.util.concurrent.ExecutorService
来监视HttpClient.executeMethod()
调用。
这是一个小而独立的例子
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
/**
* @author Jeff Kirby
* @since <pre>Jun 17, 2011</pre>
*/
public class Example {
private static final String SITE = "http://some.website.com/upload";
private static final int TIME_OUT_SECS = 5;
// upload a file and return the response as a string
public String post(File file) throws IOException, InterruptedException {
final Part[] multiPart = { new FilePart("file", file.getName(), file) };
final EntityEnclosingMethod post = new PostMethod(SITE);
post.setRequestEntity(new MultipartRequestEntity(multiPart, post.getParams()));
final ExecutorService executor = Executors.newSingleThreadExecutor();
final List<Future<Integer>> futures = executor.invokeAll(Arrays.asList(new KillableHttpClient(post)), TIME_OUT_SECS, TimeUnit.SECONDS);
executor.shutdown();
if(futures.get(0).isCancelled()) {
throw new IOException(SITE + " has timed out. It has taken more than " + TIME_OUT_SECS + " seconds to respond");
}
return post.getResponseBodyAsString();
}
private static class KillableHttpClient implements Callable<Integer> {
private final EntityEnclosingMethod post;
private KillableHttpClient(EntityEnclosingMethod post) {
this.post = post;
}
public Integer call() throws Exception {
return new HttpClient().executeMethod(post);
}
}
}
从版本4.3开始,不推荐使用Laz最高版本的所述方法。 因此,最好使用Request Config Object然后构建HTTP Client
private CloseableHttpClient createHttpClient()
{
CloseableHttpClient httpClient;
CommonHelperFunctions helperFunctions = new CommonHelperFunctions();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(306);
cm.setDefaultMaxPerRoute(108);
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(15000)
.setSocketTimeout(15000).build();
httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig).build();
return httpClient;
}
PoolingHttpClientConnectionManager用户可以设置最大默认连接数和每条路径的最大连续数。 我分别设置为306和108。 对于大多数情况,默认值是不够的。
设置超时:我使用了RequestConfig对象。 您还可以设置属性Connection Request Timeout,以设置从Connection Manager等待连接的超时。
上面的benvoliot在评论中已经提到过这一点。 但是,我认为它值得一个顶级职位,因为它确实让我摸不着头脑。 我发布这个,以防它帮助其他人。
我编写了一个简单的测试客户端,在这种情况下CoreConnectionPNames.CONNECTION_TIMEOUT
超时工作完美。 如果服务器没有响应,请求将被取消。
在服务器代码中,我实际上是在尝试测试,但相同的代码永远不会超时。
将它更改为套接字连接活动( CoreConnectionPNames.SO_TIMEOUT
)而不是HTTP连接( CoreConnectionPNames.CONNECTION_TIMEOUT
)的超时时间为我解决了问题。
另外,请仔细阅读Apache文档: http : //hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/params/CoreConnectionPNames.html#CONNECTION_TIMEOUT
注意说的那一点
请注意,此参数只能应用于绑定到特定本地地址的连接。
我希望拯救别人所有的头脑刮伤我经历过。 这将教我不要彻底阅读文档!
Op后来表示他们使用的是Apache Commons HttpClient 3.0.1
HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
client.getHttpConnectionManager().getParams().setSoTimeout(5000);
HttpConnectionParams.setSoTimeout(params, 10*60*1000);// for 10 mins i have set the timeout
您也可以定义所需的时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.