为何 RestTemplate 无法定制请求 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cocong
V2EX    Java

为何 RestTemplate 无法定制请求

  •  
  •   cocong
    hzh-cocong 1 天前 935 次点击

    我们项目都是配置一个 RestTemplate bean ,然后所有外部请求都用它,现在有个需求的超时时间要求不一样,就得重新义一个 bean ,又得怼一堆配置,麻烦,直接用 simpleClientHttpRequestFactory 又不能用到连接池,所以为何 RestTemplate 不支持对每个请求定制化,就像事务超时设置 @Transactional(timeout = 3),每个都可以不一样,唯独这个外部请求没有这种功能,就感觉不太合理。

    问了 AI ,可以用下面的方法,但感觉还是太麻烦了,不够简单优雅

    步骤 1:创建一个全局共享的、带连接池的 CloseableHttpClient

    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); } } 

    步骤 2:在业务代码中直接调用(无需 Spring Bean )

    // 动态构造请求头 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 ); 
    8 条回复    2025-11-07 18:29:16 +08:00
    xtreme1
        1
    xtreme1  
       1 天前
    用 WebClient, 可以拿到一个 CompletableFuture
    potatowish
        2
    potatowish  
       1 天前 via iPhone
    spring 5.0 webclient 就可以吧,每个请求可以单独设置超时时间
    momo31
        3
    momo31  
       1 天前
    直接用 okhttp 呢
    tedzhou1221
        4
    tedzhou1221  
       23 小时 59 分钟前
    我们之前的项目改用 Forest http
    doppler
        5
    doppler  
       23 小时 45 分钟前
    用 webclient 加 timeout 操作符
    nananqujava
        6
    nananqujava  
       23 小时 41 分钟前
    Forest 好用 https://forest.kim/
    Need4more
        7
    Need4more  
       17 小时 35 分钟前
    你这太罗嗦了,用 RestTemplateBuilder

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder
    .setConnectTimeout(Duration.ofSeconds(5))
    .setReadTimeout(Duration.ofSeconds(5))
    .build();
    }
    looo
        8
    looo  
       16 小时 49 分钟前
    @Need4more 我之前项目也是这么搞,一个三方一个 bean ,每一家的接口超时不一样
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2836 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 21ms UTC 03:18 PVG 11:18 LAX 19:18 JFK 22:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86