如何配置Spring的RestTemplate支持HTTP/2请求?其他客户端有相关选项吗?
刚好之前折腾过RestTemplate的HTTP/2配置,给你捋捋清楚:RestTemplate本身只是个上层封装,它的HTTP协议支持完全靠底层的ClientHttpRequestFactory实现。默认的SimpleClientHttpRequestFactory基于JDK自带的HttpURLConnection,根本不支持HTTP/2,所以得换成支持HTTP/2的客户端实现,比如Apache HttpClient 5或者OkHttp。
方案一:使用Apache HttpClient 5配置
1. 引入依赖(Maven为例)
<dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.2.1</version> <!-- 用最新稳定版即可 --> </dependency> <dependency> <groupId>org.apache.httpcomponents.core5</groupId> <artifactId>httpcore5-h2</artifactId> <version>5.2.1</version> </dependency>
2. 配置HTTP/2支持的HttpClient并注入RestTemplate
import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.core5.http.config.Registry; import org.apache.hc.core5.http.config.RegistryBuilder; import org.apache.hc.core5.http.io.SocketConfig; import org.apache.hc.core5.http.ssl.TLS; import org.apache.hc.core5.ssl.SSLContexts; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @Configuration public class RestTemplateConfig { @Bean public RestTemplate http2RestTemplate() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { // 构建支持HTTP/2的SSL上下文(HTTP/2要求TLS 1.2+) SSLContext sslContext = SSLContexts.custom() .setProtocol(TLS.V_1_2) .build(); // 注册HTTP/1.1和HTTP/2的Socket工厂 Registry<SSLConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<SSLConnectionSocketFactory>create() .register("http", SSLConnectionSocketFactory.getSocketFactory()) .register("https", new SSLConnectionSocketFactory(sslContext, TLS.V_1_2, null, null)) .build(); // 配置连接管理器,启用HTTP/2支持 HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create() .setSSLSocketFactoryRegistry(socketFactoryRegistry) .setDefaultSocketConfig(SocketConfig.custom() .setSoTimeout(5000) .build()) .build(); // 创建支持HTTP/2的HttpClient实例 org.apache.hc.client5.http.classic.HttpClient httpClient = HttpClients.custom() .setConnectionManager(connectionManager) .build(); // 包装成RestTemplate可用的请求工厂 HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); requestFactory.setConnectTimeout(5000); requestFactory.setReadTimeout(5000); return new RestTemplate(requestFactory); } }
方案二:使用OkHttp配置
OkHttp对HTTP/2的支持更省心,默认就启用了HTTP/2协商(只要服务器支持)。
1. 引入依赖(Maven为例)
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.10.0</version> <!-- 最新稳定版 --> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- Spring Boot项目自带RestTemplate基础依赖 --> </dependency>
2. 配置OkHttpClient并注入RestTemplate
import okhttp3.OkHttpClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import java.time.Duration; @Configuration public class RestTemplateConfig { @Bean public RestTemplate http2RestTemplate() { OkHttpClient okHttpClient = new OkHttpClient.Builder() .connectTimeout(Duration.ofSeconds(5)) .readTimeout(Duration.ofSeconds(5)) .writeTimeout(Duration.ofSeconds(5)) // OkHttp默认启用HTTP/2,无需额外配置,服务器支持就会自动切换 .build(); OkHttp3ClientHttpRequestFactory requestFactory = new OkHttp3ClientHttpRequestFactory(okHttpClient); return new RestTemplate(requestFactory); } }
关于Spring生态中支持HTTP/2的客户端选项
除了给RestTemplate换底层工厂,还有几个更推荐的选择:
WebClient(Spring 5+官方推荐):这是Spring主推的非阻塞、响应式HTTP客户端,天然支持HTTP/2(底层依赖的Reactor Netty默认支持HTTP/2)。RestTemplate已经进入维护模式,如果你的项目是Spring Boot 2.x+或者Spring 5+,更建议用WebClient替代。
Spring Cloud LoadBalancer + WebClient:如果需要负载均衡,结合Spring Cloud LoadBalancer的WebClient客户端也能轻松支持HTTP/2。
最后要注意:不管用哪种客户端,服务器端必须支持HTTP/2,否则客户端会自动降级到HTTP/1.1。你可以通过查看响应头的HTTP/2标识或者抓包工具(比如Wireshark)来验证是否成功使用了HTTP/2。
内容的提问来源于stack exchange,提问作者the_kaba




