我们项目都是配置一个 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
);
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.