在SpringBoot 2.1.x中使用RestTemplateBuilder的requestFactory的自定义RestTemplate与1.5.x版本不向后兼容

时间:2018-11-28 03:02:43

标签: java spring-boot resttemplate

Spring Boot 1.5.x 中,我正在创建一个自定义case SET_BOOKMARK: return state.setIn(['result', 'Bookmark'], action.payload.total) ,如下所示:

RestTemplate

但是,在迁移到 Spring Boot 2.1.x 之后,以上代码无法编译。看起来@Bean public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) { PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(); poolingConnectionManager.setMaxTotal(restTemplateProps.getMaxConnectionsPerPool()); poolingConnectionManager.setDefaultMaxPerRoute(restTemplateProps.getMaxDefaultConnectionPerRoute()); CloseableHttpClient client = HttpClientBuilder.create().setConnectionManager(poolingConnectionManager).build(); HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(client); clientHttpRequestFactory.setConnectTimeout(restTemplateProps.getConnectionTimeout()); clientHttpRequestFactory.setReadTimeout(restTemplateProps.getSocketTimeout()); return restTemplateBuilder.requestFactory(clientHttpRequestFactory).build(); } 并没有将requestFactory作为输入参数。

谁能建议我如何在Spring Boot 2.1.x中实现以上代码?

4 个答案:

答案 0 :(得分:6)

深入研究 Spring Boot 2.1.x RestTemplateBuilder的源代码之后,我发现他们已经删除了方法requestFactory(ClientHttpRequestFactory requestFactory) 。这意味着您不能再将ClientHttpRequestFactory对象注入requestFactory方法中。

但是,它现在接受Supplier<ClientHttpRequestFactory>作为输入。因此,如果您只有一个restTemplate和一个requestFactory,那么您要做的就是在Spring上下文中注册一个HttpComponentsClientHttpRequestFactory bean,并将ClientHttpRequestFactorySupplier传递给requestFactory方法。供应商将自动检测到您的HttpComponentsClientHttpRequestFactory并返回给您所需的RestTemplate。

请参考以下代码:

@Bean
  public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory() {
    PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager();
    poolingConnectionManager.setMaxTotal(restTemplateProps.getMaxConnectionsPerPool());
    poolingConnectionManager.setDefaultMaxPerRoute(restTemplateProps.getMaxDefaultConnectionPerRoute());
    CloseableHttpClient client = HttpClientBuilder.create().setConnectionManager(poolingConnectionManager).build();
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
        new HttpComponentsClientHttpRequestFactory(client);
    clientHttpRequestFactory.setConnectTimeout(restTemplateProps.getConnectionTimeout());
    clientHttpRequestFactory.setReadTimeout(restTemplateProps.getSocketTimeout());
    return clientHttpRequestFactory;
  }

  @Bean
  public RestTemplate authRestTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.requestFactory(new ClientHttpRequestFactorySupplier()).build();
  }

对于那些对SpringBoot 2.1.x中RestTemplateBuilder所做的所有更改感兴趣的人,请参考this

答案 1 :(得分:4)

或更简单,只是:

 restTemplatebuilder.requestFactory(() -> new 
    HttpComponentsClientHttpRequestFactory(httpClient)).build();

答案 2 :(得分:1)

如果您有多个需要不同的requestFactories的restTemplate(而不是自动注入找到的第一个),这是一个更通用的解决方案:

@Configuration
public class Config {

  @Bean
  public RestTemplate restTemplate(RestTemplateBuilder builder, ApplicationContext ctx) {
    return builder.requestFactory(new MyRequestFactorySupplier()).build();
  }

  class MyRequestFactorySupplier implements Supplier<ClientHttpRequestFactory> {

    @Override
    public ClientHttpRequestFactory get() {

      // Using Apache HTTP client.
      HttpClientBuilder clientBuilder = HttpClientBuilder.create();
      HttpClient httpClient = clientBuilder.build();
      HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
      requestFactory.setBufferRequestBody(false); // When sending large amounts of data via POST or PUT, it is recommended to change this property to false, so as not to run out of memory.
      return requestFactory;
    }

  }

}

答案 3 :(得分:0)

您也可以执行以下操作:

restTemplatebuilder.requestFactory(() -> { return new 
    HttpComponentsClientHttpRequestFactory(httpClient);});