springboot使用RestTemplate+httpclient连接池发送http消息
简介
- RestTemplate是spring支持的一个请求http rest服务的模板对象,性质上有点像jdbcTemplate
- RestTemplate底层还是使用的httpclient(org.apache.http.client.HttpClient)发送请求的
- HttpClient可以做连接池,而发送消息的工具类可以使用RestTemplate,所以如果你的项目需求http连接池,RestTemplate+httpclient连接池是一种不错的方式,可以节省开发工作,也可以更优雅的使用。
配置
- maven依赖
12345678910<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>
4.5
.
6
</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- Java配置类
12345678910111213141516171819package
com.jinjian.rt.config;
import
lombok.Data;
import
org.springframework.boot.context.properties.ConfigurationProperties;
import
org.springframework.stereotype.Component;
@Component
@ConfigurationProperties
(prefix =
"http-pool"
)
@Data
public
class
HttpPoolProperties {
private
Integer maxTotal;
private
Integer defaultMaxPerRoute;
private
Integer connectTimeout;
private
Integer connectionRequestTimeout;
private
Integer socketTimeout;
private
Integer validateAfterInactivity;
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455package
com.jinjian.rt.config;
import
org.apache.http.client.HttpClient;
import
org.apache.http.client.config.RequestConfig;
import
org.apache.http.config.Registry;
import
org.apache.http.config.RegistryBuilder;
import
org.apache.http.conn.socket.ConnectionSocketFactory;
import
org.apache.http.conn.socket.PlainConnectionSocketFactory;
import
org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import
org.apache.http.impl.client.HttpClientBuilder;
import
org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import
org.springframework.beans.factory.annotation.Autowired;
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
public
class
RestTemplateConfig {
@Autowired
private
HttpPoolProperties httpPoolProperties;
@Bean
public
RestTemplate restTemplate() {
return
new
RestTemplate(httpRequestFactory());
}
@Bean
public
ClientHttpRequestFactory httpRequestFactory() {
return
new
HttpComponentsClientHttpRequestFactory(httpClient());
}
@Bean
public
HttpClient httpClient() {
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register(
"http"
, PlainConnectionSocketFactory.getSocketFactory())
.register(
"https"
, SSLConnectionSocketFactory.getSocketFactory())
.build();
PoolingHttpClientConnectionManager connectionManager =
new
PoolingHttpClientConnectionManager(registry);
connectionManager.setMaxTotal(httpPoolProperties.getMaxTotal());
connectionManager.setDefaultMaxPerRoute(httpPoolProperties.getDefaultMaxPerRoute());
connectionManager.setValidateAfterInactivity(httpPoolProperties.getValidateAfterInactivity());
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(httpPoolProperties.getSocketTimeout())
//服务器返回数据(response)的时间,超过抛出read timeout
.setConnectTimeout(httpPoolProperties.getConnectTimeout())
//连接上服务器(握手成功)的时间,超出抛出connect timeout
.setConnectionRequestTimeout(httpPoolProperties.getConnectionRequestTimeout())
//从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
.build();
return
HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(connectionManager)
.build();
}
}
-
使用方法
1234567891011121314151617181920212223242526272829303132333435363738package
com.jinjian.rt.service;
import
com.jinjian.rt.dto.RuiooResponseEntity;
import
org.json.JSONException;
import
org.json.JSONObject;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.http.ResponseEntity;
import
org.springframework.stereotype.Service;
import
org.springframework.web.client.RestTemplate;
import
java.io.IOException;
@Service
public
class
TestService {
@Autowired
private
RestTemplate restTemplate;
public
void
startTest()
throws
JSONException, IOException {
JSONObject jsonObject =
new
JSONObject();
jsonObject.put(
"first"
,
"jinjian"
);
jsonObject.put(
"second"
,
"aaaaaaa"
);
long
start = System.currentTimeMillis();
//{1} 表示第一个占位符,也可以填写name,但是这是另一个getForEntity重载方法
//RuiooResponseEntity 为自定义dto
ResponseEntity<RuiooResponseEntity> entity = restTemplate.getForEntity(
"http://39.107.104.221/api/test/{1}"
, RuiooResponseEntity.
class
,
123
);
long
end = System.currentTimeMillis();
long
cost = end - start;
System.out.println(
"耗时:"
+cost);
RuiooResponseEntity body = entity.getBody();
body.getData();
body.getStatus();
body.getMessage();
System.out.println(
"响应体:"
+ body);
}
}
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
【推荐】AI 的力量,开发者的翅膀:欢迎使用 AI 原生开发工具 TRAE
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战
· 当加密ID需要变成Guid:为什么我选择了AES-CBC而非GCM?
· 基于 epoll 的协程调度器——零基础深入浅出 C++20 协程
· 下划线字段在golang结构体中的应用
· SQL Server也能玩正则表达式?
· CUDA 编程初探
· 家里有密码锁的注意了,这真不是 BUG,是 feature。
· C#实现屏幕墙:同时监控多个电脑桌面(支持Windows、信创Linux、银河麒麟、统信UOS)
· 直击痛点的开源项目「GitHub 热点速览」
· C# 13 与 .NET 9 跨平台开发实战(第一章:开发环境搭建与.NET概述-上篇)
· 记一次 .NET 某自动化智能制造软件 卡死分析