You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7迁移至Spring Boot 3的HttpClient适配问题

Spring Boot 2 迁移至 Spring Boot 3 时 RestTemplate 配置问题解决

问题背景

将Spring Boot 2项目迁移至Spring Boot 3后,原RestTemplate的HttpClient配置代码出现报错,替换为HttpClient5相关类后,又遇到setDefaultSocketConfig方法不存在的问题。

原Spring Boot 2配置代码

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.util.concurrent.TimeUnit;
import org.apache.http.HttpHost;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients; 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate; 

@Configuration
@RefreshScope
public class RestTemplateConfig{

    int timeout=10000;
    int readTimeout=10000;
    int retryCount=3;
    int timeToLive=5000;
    String rProxy="proxy.test.com";
    String rPort="80";

    public RestTemplate restTemplate() {
        return new RestTemplate(getClientHttpRequestFactory());
    }

    private ClientHttpRequestFactory getClientHttpRequestFactory() {

        HttpHost proxy = new HttpHost(rProxy, Integer.parseInt(rPort));

        SocketConfig socketConfig=SocketConfig.custom()
                              .setSoTimeout(timeout)
                              .build();

        RequestConfig requestConfig=RequestConfig.custom()
                                .setConnectionRequestTimeout(timeout)
                                .setConnectTimeout(timeout)
                                .setSocketTimeout(timeout)
                                .build(); 

        HttpClient httpClient=HttpClients.custom().setProxy(proxy)
                                              .setDefaultSocketConfig(socketConfig)
                                              .setDefaultRequestConfig(requestConfig)
                                              .setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, true))
                                              .setConnectionTimeToLive(timeToLive, TimeUnit.MILLISECONDS)
                                              .build(); 

        HttpComponentsClientHttpRequestFactory rf=new HttpComponentsClientHttpRequestFactory(httpClient);
        rf.setConnectTimeout(timeout); 
        rf.setReadTimeout(readTimeout);
        rf.setConnectionRequestTimeout(timeout);

        return rf;
    }
}

第一次报错

The constructor HttpComponsentsClientHttpRequestFactory(HttpClient) is undefined.

原因是Spring Boot 3中HttpComponentsClientHttpRequestFactory的构造方法仅接受org.apache.hc.client5.http.classic.HttpClient类型,因此需要将相关类替换为HttpClient5的版本。

替换后的新报错

替换导入的HttpClient相关类为:

import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.HttpHost;
import org.apache.hc.client5.http.impl.classic.HttpClients;

此时出现新报错:

The method setDefaultSocketConfig(SocketConfig) is undefined for the type HttpClientBuilder

解决方案

在HttpClient5中,SocketConfig相关配置已整合到RequestConfig或ConnectionConfig中,同时多个API名称也发生了变化,以下是适配后的完整配置代码:

import java.util.concurrent.TimeUnit;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.HttpHost;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
import org.apache.hc.core5.util.Timeout;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate; 

@Configuration
@RefreshScope
public class RestTemplateConfig{

    int timeout=10000;
    int readTimeout=10000;
    int retryCount=3;
    int timeToLive=5000;
    String rProxy="proxy.test.com";
    String rPort="80";

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate(getClientHttpRequestFactory());
    }

    private ClientHttpRequestFactory getClientHttpRequestFactory() {
        // 配置代理
        HttpHost proxy = new HttpHost(rProxy, Integer.parseInt(rPort));

        // 配置请求参数,包含原SocketConfig的soTimeout设置
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(Timeout.ofMilliseconds(timeout))
                .setConnectionRequestTimeout(Timeout.ofMilliseconds(timeout))
                .setResponseTimeout(Timeout.ofMilliseconds(timeout)) // 对应原SocketConfig的soTimeout
                .build();

        // 配置连接池及连接存活时间
        var connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
                .setConnectionTimeToLive(timeToLive, TimeUnit.MILLISECONDS)
                .build();

        // 构建HttpClient
        HttpClient httpClient = HttpClients.custom()
                .setProxy(proxy)
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .setRetryStrategy(new DefaultHttpRequestRetryStrategy(retryCount, Timeout.ofSeconds(1))) // 替换原DefaultHttpRequestRetryHandler
                .build();

        HttpComponentsClientHttpRequestFactory rf = new HttpComponentsClientHttpRequestFactory(httpClient);
        rf.setConnectTimeout(timeout);
        rf.setReadTimeout(readTimeout);
        rf.setConnectionRequestTimeout(timeout);

        return rf;
    }
}

关键变化说明

  1. SocketConfig替代:原SocketConfig的soTimeout已整合到RequestConfig的setResponseTimeout方法中,使用Timeout.ofMilliseconds()设置超时时间。
  2. 重试处理器替换:DefaultHttpRequestRetryHandler替换为DefaultHttpRequestRetryStrategy,构造参数需传入重试次数和重试间隔超时。
  3. 连接存活时间配置:原setConnectionTimeToLive需通过PoolingHttpClientConnectionManagerBuilder来配置,不再直接在HttpClientBuilder上设置。
  4. 超时参数类型:HttpClient5中部分超时参数使用Timeout类型替代原有的int毫秒值,需用Timeout.ofMilliseconds()或Timeout.ofSeconds()转换。

内容的提问来源于stack exchange,提问作者Kalai Selvan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:01:03