{"id":1979,"date":"2023-04-01T10:42:08","date_gmt":"2023-04-01T02:42:08","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=1979"},"modified":"2023-04-22T08:28:37","modified_gmt":"2023-04-22T00:28:37","slug":"resttemplate-httpclient-dynamically-set-timeout-time","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/04\/01\/resttemplate-httpclient-dynamically-set-timeout-time\/","title":{"rendered":"RestTemplate\uff08httpclient\uff09\u52a8\u6001\u8bbe\u7f6e\u8d85\u65f6\u65f6\u95f4"},"content":{"rendered":"<h2>\u57fa\u672c\u5b9e\u73b0<\/h2>\n<h3>httpclient\u7248\u672c<\/h3>\n<pre><code class=\"language-xml\">&lt;dependency&gt;\n    &lt;groupId&gt;org.apache.httpcomponents&lt;\/groupId&gt;\n    &lt;artifactId&gt;httpclient&lt;\/artifactId&gt;\n    &lt;version&gt;4.5.2&lt;\/version&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n<p><!-- more --><\/p>\n<h3>RestTemplate\u6784\u9020<\/h3>\n<pre><code class=\"language-java\">HttpClientBuilder httpClientBuilder = HttpClients.custom();\n\/\/ HttpClient\u76f8\u5173\u914d\u7f6e\nHttpClient httpClient = httpClientBuilder.build();\n\n\/\/ \u4f7f\u7528\u81ea\u5b9a\u4e49HttpClientRequestFactory\nHttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpClientRequestFactory(httpClient);\nclientHttpRequestFactory.setConnectTimeout(5000);\n\/\/ \u5373\u4e3a SocketTimeout\nclientHttpRequestFactory.setReadTimeout(30000);  \nclientHttpRequestFactory.setConnectionRequestTimeout(5000);\n\nRestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory)<\/code><\/pre>\n<h3>HttpClientRequestFactory\u7c7b<\/h3>\n<pre><code class=\"language-java\">import org.apache.http.client.HttpClient;\nimport org.apache.http.client.config.RequestConfig;\nimport org.apache.http.client.protocol.HttpClientContext;\nimport org.apache.http.protocol.HttpContext;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.client.HttpComponentsClientHttpRequestFactory;\n\nimport java.net.URI;\n\npublic class HttpClientRequestFactory extends HttpComponentsClientHttpRequestFactory {\n\n    public static ThreadLocal&lt;Integer&gt; socketTimeoutThreadLocal = new ThreadLocal&lt;&gt;();\n\n    public HttpClientRequestFactory(HttpClient httpClient) {\n        super(httpClient);\n    }\n\n    @Override\n    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {\n        HttpContext context = HttpClientContext.create();\n\n        RequestConfig config = createRequestConfig(getHttpClient());\n\n        \/\/ \u4eceThreadLocal\u4e2d\u83b7\u53d6\u8d85\u65f6\u65f6\u95f4\uff0c\u5e76\u8bbe\u7f6e\u5230context\u4e2d\n        Integer socketTimeout = socketTimeoutThreadLocal.get();\n        if (null != socketTimeout) {\n            RequestConfig.Builder builder = RequestConfig.copy(config);\n            builder.setSocketTimeout(socketTimeout);\n            config = builder.build();\n        }\n\n        context.setAttribute(HttpClientContext.REQUEST_CONFIG, config);\n        return context;\n    }\n}<\/code><\/pre>\n<h3>\u4f7f\u7528\u65b9\u6cd5<\/h3>\n<pre><code class=\"language-java\">\/\/ \u8bbe\u7f6e\u5f53\u524d\u8bf7\u6c42\u8d85\u65f6\u65f6\u95f4\nHttpClientRequestFactory.socketTimeoutThreadLocal.set(15000);\ntry {\n    restTemplate.***()\n} finally {\n    \/\/ \u6e05\u7406ThreadLocal\u4e2d\u8d85\u65f6\u65f6\u95f4\n    HttpClientRequestFactory.socketTimeoutThreadLocal.remove();\n}<\/code><\/pre>\n<h3>\u539f\u7406\u89e3\u6790<\/h3>\n<pre><code class=\"language-java\">org.apache.http.impl.execchain.MainClientExec.execute(...)<\/code><\/pre>\n<p>httpclient\u5728\u53d1\u8d77\u8bf7\u6c42\u65f6\u4f1a\u4f18\u5148\u4f7f\u7528context\u4e2d\u7684\u8d85\u65f6\u65f6\u95f4\u8bbe\u7f6e<\/p>\n<pre><code class=\"language-java\">final RequestConfig config = context.getRequestConfig();\n...\nfinal int timeout = config.getSocketTimeout();\nif (timeout &gt;= 0) {\n    managedConn.setSocketTimeout(timeout);\n}<\/code><\/pre>\n<h2>\u4f7f\u7528\u6848\u4f8b<\/h2>\n<pre><code class=\"language-java\">import org.apache.http.client.HttpClient;\nimport org.apache.http.client.config.RequestConfig;\nimport org.apache.http.client.methods.HttpEntityEnclosingRequestBase;\nimport org.apache.http.client.methods.HttpUriRequest;\nimport org.apache.http.client.protocol.HttpClientContext;\nimport org.apache.http.protocol.HttpContext;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.client.HttpComponentsClientHttpRequestFactory;\n\nimport java.net.URI;\n\npublic class HttpClientRequestFactory extends HttpComponentsClientHttpRequestFactory {\n\n    private static ThreadLocal&lt;Integer&gt; SOCKET_TIMEOUT_THREAD_LOCAL = new ThreadLocal&lt;&gt;();\n\n    public HttpClientRequestFactory(HttpClient httpClient) {\n\n        super(httpClient);\n    }\n\n    @Override\n    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {\n\n        HttpContext context = HttpClientContext.create();\n        RequestConfig config = createRequestConfig(getHttpClient());\n\n        Integer socketTimeout = SOCKET_TIMEOUT_THREAD_LOCAL.get();\n        if (null != socketTimeout) {\n            RequestConfig.Builder builder = RequestConfig.copy(config);\n            builder.setSocketTimeout(socketTimeout);\n            config = builder.build();\n        }\n\n        context.setAttribute(HttpClientContext.REQUEST_CONFIG, config);\n        return context;\n    }\n\n    @Override\n    protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {\n\n        if (httpMethod == HttpMethod.GET) {\n            return new HttpGetRequestForBody(uri);\n        }\n        return super.createHttpUriRequest(httpMethod, uri);\n    }\n\n    private static final class HttpGetRequestForBody extends HttpEntityEnclosingRequestBase {\n        public HttpGetRequestForBody(final URI uri) {\n\n            super.setURI(uri);\n        }\n\n        @Override\n        public String getMethod() {\n\n            return HttpMethod.GET.name();\n        }\n    }\n\n    public static void set(Integer timeoutMills) {\n\n        SOCKET_TIMEOUT_THREAD_LOCAL.set(timeoutMills);\n    }\n\n    public static void remove() {\n\n        SOCKET_TIMEOUT_THREAD_LOCAL.remove();\n    }\n}<\/code><\/pre>\n<pre><code class=\"language-java\">HttpClientRequestFactory.set(6000);\nResult&lt;ChannelsPayResponse&gt; payCreateResult;\ntry {\n    HttpEntity&lt;ChannelsPayRequest&gt; requestEntity = new HttpEntity&lt;&gt;(request, getHttpHeaders());\n    ParameterizedTypeReference&lt;Result&lt;ChannelsPayResponse&gt;&gt; parameterizedTypeReference =\n            new ParameterizedTypeReference&lt;Result&lt;ChannelsPayResponse&gt;&gt;() {};\n    ResponseEntity&lt;Result&lt;ChannelsPayResponse&gt;&gt; responseEntity = restTemplate.exchange(String.format(&quot;http:\/\/%s\/channels\/pay&quot;, channelService.getServiceAppName()),\n            HttpMethod.POST, requestEntity, parameterizedTypeReference);\n    payCreateResult = responseEntity.getBody();\n    log.info(JsonUtils.beanToJson(payCreateResult));\n} catch (Exception e) {\n    if (e.getCause() instanceof SocketTimeoutException) {\n        Result&lt;ChannelsPayQueryResponse&gt; payQueryResult;\n        try {\n            HttpEntity&lt;ChannelsPayQueryRequest&gt; requestEntity = new HttpEntity&lt;&gt;(request, getHttpHeaders());\n            ParameterizedTypeReference&lt;Result&lt;ChannelsPayQueryResponse&gt;&gt; parameterizedTypeReference =\n                    new ParameterizedTypeReference&lt;Result&lt;ChannelsPayQueryResponse&gt;&gt;() {};\n            ResponseEntity&lt;Result&lt;ChannelsPayQueryResponse&gt;&gt; responseEntity = restTemplate.exchange(String.format(&quot;http:\/\/%s\/channels\/pay\/query&quot;, channelService.getServiceAppName()),\n                    HttpMethod.POST, requestEntity, parameterizedTypeReference);\n            payQueryResult = responseEntity.getBody();\n            log.info(JsonUtils.beanToJson(payQueryResult));\n        } catch (Exception e) {\n            log.error(&quot;&quot;, e);\n            throw e;\n        }\n    }\n} finally {\n    HttpClientRequestFactory.remove();\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u57fa\u672c\u5b9e\u73b0 httpclient\u7248\u672c &lt;dependency&gt; &lt;groupId&gt;org [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[253],"class_list":["post-1979","post","type-post","status-publish","format-standard","hentry","category-spring-boot","tag-resttemplate"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1979","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=1979"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1979\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=1979"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=1979"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=1979"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}