제한 시간이 정의 된 Java HTTP 클라이언트 요청


92

내 클라우드의 여러 서버에 BIT (Built in tests)를 만들고 싶습니다. 큰 시간 초과시 실패하는 요청이 필요합니다.

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("");
 }
}

-편집 : 사용중인 라이브러리를 명확히-

아파치에서 httpclient를 사용하고 있습니다. 여기에 관련 pom.xml 섹션이 있습니다.

 <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.0.1</version>
   <type>jar</type>
 </dependency>

모든 HTTP 기능에 어떤 라이브러리를 사용하고 있습니까?
nojo

댓글 감사합니다. 내 게시물을 업데이트했습니다.
Maxim Veksler 2010 년

답변:


119
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);

1
이것은 무엇을합니까? 설정 한 시간 초과? stackoverflow.com/questions/3000767/…을
Maxim Veksler 2010 년

84
Apache의 HttpClient에는 두 개의 개별 시간 제한이 있습니다. 하나는 TCP 연결을 설정하기 위해 대기하는 시간 제한이고 다른 하나는 후속 데이터 바이트를 기다리는 시간입니다. HttpConnectionParams.setConnectionTimeout ()은 전자이고 HttpConnectionParams.setSoTimeout ()은 후자입니다.
benvolioT 2011 년

7
기본 시간 제한은 무엇입니까? 0 = 무한?
Tobia

1
http.connection.timeout Integer 연결이 설정 될 때까지의 제한 시간입니다. 0 값은 제한 시간이 사용되지 않음을 의미합니다.
maveroid

27
미래의 독자들에게 : 여기에 참조 된 클래스는 이제 더 이상 사용되지 않습니다 (2016-07-05 기준). 2010 년에 게시되었을 때 좋은 답변 일 수 있습니다.이 답변을 참조하십시오. stackoverflow.com/a/ 19153314/192801 은 좀 더 최신입니다.
FrustratedWithFormsDesigner

126

Http Client 버전 4.3 이상을 사용하는 경우 다음을 사용해야합니다.

RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();

4
감사! 답을 찾기 전에이 작업을 수행하기 위해 더 이상 사용되지 않는 명령을 제거하는 방법을 알아 내기 위해 적어도 20 분을 보냈습니다.
vextorspace

잊어 버렸습니다 SocketTimeout. 또한 "default" HttpClientHttpClientBuilderfrom create ()가 build()메소드를 통해 제공 하는 모든 것에 대한 기본값 임을 의미 합니까? 아니면 통과하는 것들만 setDefaultRequestConfig(requestConfig)? 내가 말이 되는가?
ADTC

@ADTC 귀하의 질문은 약간 혼란 스럽습니다 :). 기본 요청 구성은 해당 HttpClient 'only'를 사용하는 모든 HttpPost, HttpGet, ... 인스턴스에 사용됩니다. 다른 HttpClient 인스턴스를 만든 경우이 요청 구성은 해당 클라이언트에서 사용되지 않습니다.
천둥

36

HttpParams는 새로운 Apache HTTPClient 라이브러리에서 더 이상 사용되지 않습니다. Laz에서 제공하는 코드를 사용하면 지원 중단 경고가 표시됩니다.

HttpGet 또는 HttpPost 인스턴스에서 대신 RequestConfig를 사용하는 것이 좋습니다.

final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();
httpPost.setConfig(params);

"위의 코드 사용" << SO는 포럼이 아니며 여러 요인으로 인해 답변이 위 / 아래로 이동하므로 어떤 코드를 참조하고 있는지 알 수 없습니다. "xyz의 답변 코드 사용"과 같이 말씀해 주시겠습니까?
ADTC

4
Btw, 깔끔한 대답. 그러나 Thunder의 대답과 비교할 때을 기본값으로 설정하는 것과 반대로 RequestConfig모든 설정의 차이점은 무엇 입니까? HttpPostHttpClient
ADTC

2
예, 맞습니다. 위의 코드는 시간이 지남에 따라 변경되지 않아야하는 "수락 된 답변"을 나타냅니다. 어쨌든 내 대답을 업데이트하겠습니다 ..
pmartin8

10

내가 알지 못하는 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;
}

2
이것은 Apache HTTP 클라이언트의 시간 초과에 영향을주지 않습니다.
laz

9
절대로 그 짓을 주장하지)
dbyrne

5
HttpURLConnection의 시간 제한 개념이 충분하지 않습니다. 서버가 응답하기 시작했지만 중단되면 시간 초과에 도달하지 않습니다. Apache의 HttpClient는 이러한 차이 때문에 더 나은 선택입니다.
benvolioT 2011 년

7

나는의 설정에서 시간을 설정하는 것을 발견 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);
      }
   }
}

7

Laz에 의해 가장 높은 상기 방법은 버전 4.3 이상에서 더 이상 사용되지 않습니다. 따라서 요청 구성 개체를 사용하고 HTTP 클라이언트를 빌드하는 것이 좋습니다.

    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 개체를 사용했습니다. 연결 관리자의 연결 대기 시간 제한을 설정하기 위해 연결 요청 시간 제한 속성을 설정할 수도 있습니다.


5

이것은 benvoliot 의 의견에서 이미 언급되었습니다. 위의 . 그러나 나는 그것이 내 머리를 긁적이기 때문에 최상위 게시물의 가치가 있다고 생각합니다. 다른 사람에게 도움이 될 경우를 대비하여 게시하고 있습니다.

간단한 테스트 클라이언트를 작성했고이 경우 CoreConnectionPNames.CONNECTION_TIMEOUT타임 아웃이 완벽하게 작동합니다. 서버가 응답하지 않으면 요청이 취소됩니다.

서버 코드 내부에서 실제로 테스트를 시도했지만 동일한 코드가 시간 초과되지 않습니다.

CoreConnectionPNames.SO_TIMEOUTHTTP 연결 ( CoreConnectionPNames.CONNECTION_TIMEOUT)이 아닌 소켓 연결 활동 ( ) 에서 시간 초과로 변경 하면 문제가 해결되었습니다.

또한 Apache 문서를주의 깊게 읽으십시오 : http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/params/CoreConnectionPNames.html#CONNECTION_TIMEOUT

말하는 비트에 유의하십시오.

이 매개 변수는 특정 로컬 주소에 바인딩 된 연결에만 적용 할 수 있습니다.

나는 그것이 내가 겪은 모든 머리를 긁는 다른 사람을 구하기를 바랍니다. 문서를 철저히 읽지 않도록 가르쳐 줄 것입니다!


2

Op는 나중에 Apache Commons HttpClient 3.0.1을 사용하고 있다고 말했습니다.

 HttpClient client = new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
        client.getHttpConnectionManager().getParams().setSoTimeout(5000);

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.