我们项目都是配置一个 RestTemplate bean ,然后所有外部请求都用它,现在有个需求的超时时间要求不一样,就得重新定义一个 bean ,又得怼一堆配置,麻烦,直接用 simpleClientHttpRequestFactory 又不能用到连接池,所以为何 RestTemplate 不支持对每个请求定制化,就像事务超时设置 @Transactional(timeout = 3),每个都可以不一样,唯独这个外部请求没有这种功能,就感觉不太合理。
问了 AI ,可以用下面的方法,但感觉还是太麻烦了,不够简单优雅
public class PooledRestClient {
private static final CloseableHttpClient httpClient;
static {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(100);
cm.setDefaultMaxPerRoute(20);
// 可选:设置空闲连接清理
httpClient = HttpClients.custom()
.setConnectionManager(cm)
.evictIdleConnections(60, TimeUnit.SECONDS)
.build();
}
// 核心方法:动态发起请求
public static ResponseEntity<String> exchange(
String url,
HttpMethod method,
HttpEntity<?> requestEntity,
Class<String> responseType,
int connectTimeoutMs,
int readTimeoutMs) {
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory( httpClient);
factory.setConnectTimeout(connectTimeoutMs);
factory.setReadTimeout(readTimeoutMs);
RestTemplate restTemplate = new RestTemplate(factory);
return restTemplate.exchange(url, method, requestEntity, responseType);
}
}
// 动态构造请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + token);
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("{\"key\":\"value\"}", headers);
// 发起带连接池的请求(每次 URL/Token/Body 都可不同)
ResponseEntity<String> response = PooledRestClient.exchange(
"https://api.example.com/v1/data",
HttpMethod.POST,
entity,
String.class,
3000, // connect timeout
10000 // read timeout
);
1
xtreme1 1 天前
用 WebClient, 可以拿到一个 CompletableFuture
|
2
potatowish 1 天前 via iPhone
spring 5.0 webclient 就可以吧,每个请求可以单独设置超时时间
|
3
momo31 1 天前
直接用 okhttp 呢
|
4
tedzhou1221 1 天前
我们之前的项目改用 Forest http
|
5
doppler 1 天前
用 webclient 加 timeout 操作符
|
6
nananqujava 1 天前
Forest 好用 https://forest.kim/
|