RestTemplate讲解二

488 阅读2分钟

第一篇文章只是简单的讲解RestTempalte,详细请参考如下文章 juejin.cn/post/706735…, 如果在实际的项目中,会出现很多意想不到的问题。

RestTemplate只是对其他的HTTP客户端的封装,其本身并没有实现HTTP相关的基础功能。其底层实现是可以配置切换的 RestTemplate 支持至少三种HTTP客户端库。 SimpleClientHttpRequestFactory。对应的HTTP库是java JDK自带的HttpURLConnection。 HttpComponentsAsyncClientHttpRequestFactory。对应的HTTP库是Apache HttpComponents。 OkHttp3ClientHttpRequestFactory。对应的HTTP库是OkHttp

java JDK自带的HttpURLConnection是默认的底层HTTP实现客户端。

RestTTemplate配置讲解

需要替换默认实现,采用httpclient方式。

@Configuration
public class RestTemplateConfig
{
    private final HttpClientConfig httpClientConfig;

    public RestTemplateConfig(HttpClientConfig httpClientConfig) {
        this.httpClientConfig = httpClientConfig;
    }
    
    @Bean
    public RestTemplate restTemplate() 
    {
        return new RestTemplate(httpRequestFactory());
    }
    
    @Bean
    public ClientHttpRequestFactory httpRequestFactory() 
    {
        //采用httpclient方式
        return new HttpComponentsClientHttpRequestFactory(httpClient());
    }
    
    @Bean
    public HttpClient httpClient() 
    {
        ConnectionKeepAliveStrategy keepAliveStrategy = new ConnectionKeepAliveStrategy() {
            @Override
            public long getKeepAliveDuration(HttpResponse httpResponse, HttpContext httpContext) {
                return 10000;
            }
        };
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
        //连接池中最大连接数
        connectionManager.setMaxTotal(httpClientConfig.getMaxTotal());
        //每服务每次能并行接收的请求数量
        connectionManager.setDefaultMaxPerRoute(httpClientConfig.getDefaultMaxPerRoute());
        connectionManager.setValidateAfterInactivity(httpClientConfig.getValidateAfterInactivity());
        
        RequestConfig requestConfig = RequestConfig.custom()
                //指客户端和服务器建立连接后,客户端从服务器读取数据的timeout
                .setSocketTimeout(httpClientConfig.getSocketTimeout())
                //客户端与服务端连接超时时间
                .setConnectTimeout(httpClientConfig.getConnectTimeout())
                //从连接池中获取连接超时时间                .setConnectionRequestTimeout(httpClientConfig.getConnectionRequestTimeout())
                .build();        
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setConnectionManager(connectionManager);
        httpClientBuilder.setDefaultRequestConfig(requestConfig);
        //设置长连接时间
        httpClientBuilder.setKeepAliveStrategy(keepAliveStrategy);
        return httpClientBuilder.build();
    }
}

@Component
@ConfigurationProperties(prefix = "http.pool")
public class HttpClientConfig implements Serializable
{
    private static final long serialVersionUID = -4608251658338406043L;
    /**
     * 最大连接数
     */
    private Integer maxTotal;
    /**
     * 路由是对最大连接数的细分
     * 每个路由基础的连接数
     */
    private Integer defaultMaxPerRoute;
    /**
     * 连接超时时间
     */
    private Integer connectTimeout;
    /**
     * 从连接池中获取连接的超时时间
     */
    private Integer connectionRequestTimeout;
    /**
     * 服务器返回数据(response)的时间
     */
    private Integer socketTimeout;
    
    //省略get、set方法
  }  

application.yml文件中配置对应的属性

http:
  pool:
    # 连接超时
    connectTimeout: 5000
    #获取连接池中连接超时
    connectionRequestTimeout: 1000
    #每个路由最大连接数量
    defaultMaxPerRoute: 5
    # /连接池中最大连接数
    maxTotal: 5
    # 服务器返回数据(response)的时间
    socketTimeout: 5000
    #定义不活动的时间(以毫秒为单位),连接回收
    validateAfterInactivity: 30000

参数详解: connectTimeout:连接超时时间 connectionRequestTimeout:获取连接池中连接超时 defaultMaxPerRoute:每个路由默认最大连接数量。 maxTotal:连接池中最大连接数。 socketTimeout:服务器返回数据(response)的时间。 validateAfterInactivity:定义不活动的时间(以毫秒为单位),连接回收时间。