web-dev-qa-db-fra.com

RestTemplate personnalisé utilisant requestFactory de RestTemplateBuilder dans SpringBoot 2.1.x n'est pas rétrocompatible avec la version 1.5.x

Dans Spring Boot 1.5.x , je créais un RestTemplate personnalisé comme ci-dessous:

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

Mais, après la migration vers ( Spring Boot 2.1.x , le code ci-dessus ne se compile pas. On dirait que requestFactory ne prend pas HttpComponentsClientHttpRequestFactory comme paramètre d'entrée.

Quelqu'un peut-il suggérer comment puis-je obtenir le code ci-dessus dans Spring Boot 2.1.x?

7
Sahil Chhabra

Après avoir approfondi le code source de RestTemplateBuilder de Spring Boot 2.1.x, j'ai trouvé qu'ils ont supprimé la méthode requestFactory(ClientHttpRequestFactory requestFactory). Cela signifie que vous ne pouvez plus injecter l'objet ClientHttpRequestFactory dans la méthode requestFactory.

Mais, il accepte un Supplier<ClientHttpRequestFactory> comme entrée maintenant. Donc, si vous n'avez qu'un restTemplate et une requestFactory, tout ce que vous avez à faire est d'enregistrer un bean HttpComponentsClientHttpRequestFactory dans le contexte Spring et de passer une méthode ClientHttpRequestFactorySupplier à requestFactory. Le fournisseur détectera automatiquement votre HttpComponentsClientHttpRequestFactory et vous renverra le RestTemplate requis.

Référez-vous au code ci-dessous pour cela:

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

Pour ceux qui sont intéressés par toutes les modifications apportées à RestTemplateBuilder dans SpringBoot 2.1.x, veuillez consulter this .

8
Sahil Chhabra

Voici une solution plus générale si vous avez plusieurs restTemplates qui nécessitent des requestFactories différentes (et non une auto-injection du premier trouvé):

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

  }

}
1
Tristan