제한 시간이 정의 된 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" HttpClient는 HttpClientBuilderfrom 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.