1
resposta

Após atualizar spring-boot-parent HttpComponentsClientHttpRequestFactory não aceita CloseableHttpClient

Após atualizar spring-boot-starter-parent de 2.6.0 para 3.0.5 estou tendo o seguinte erro "The constructor HttpComponentsClientHttpRequestFactory(CloseableHttpClient) is undefined", mas o CloseableHttpClient implementa Httpclient.

{ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List;

import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.BufferingClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.ResourceHttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; import org.springframework.http.converter.xml.SourceHttpMessageConverter; import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration public class RestTemplateConfiguration {

@Bean
RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder, ObjectMapper objectMapper, ProjetoProperties properties) {

    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(properties.getConnectTimeout())
            .setConnectionRequestTimeout(properties.getConnectionRequestTimeout())
            .setSocketTimeout(properties.getSocketTimeout())
            .build();


    List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();

    RestTemplate restTemplate = restTemplateBuilder.requestFactory(() -> {
        CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
        return new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
    }).build();

    for (HttpMessageConverter<?> messageConverter : restTemplate.getMessageConverters()) {
        if (messageConverter instanceof MappingJackson2HttpMessageConverter) {
            ((MappingJackson2HttpMessageConverter) messageConverter).setObjectMapper(objectMapper);
        } else if (messageConverter instanceof AllEncompassingFormHttpMessageConverter) {
            List<HttpMessageConverter<?>> partConverters = new ArrayList<>();
            partConverters.add(new ByteArrayHttpMessageConverter());
            partConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
            partConverters.add(new ResourceHttpMessageConverter());
            partConverters.add(new SourceHttpMessageConverter<>());
            partConverters.add(new MappingJackson2HttpMessageConverter(objectMapper));
            ((AllEncompassingFormHttpMessageConverter) messageConverter).setPartConverters(partConverters);
        } else if (messageConverter instanceof StringHttpMessageConverter) {
            messageConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
        }
        messageConverters.add(messageConverter);
    }

    restTemplate.setMessageConverters(messageConverters);

    return restTemplate;
}

} }

1 resposta

Olá Bruno, tudo bem?

Para subir do spring boot 2.x para o novo 3.x no seu projeto Java é necessário seguir os passos do guia de migração: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide

Uma das mudanças foi justamente no RestTemplate:

Apache HttpClient in RestTemplate
Support for Apache HttpClient has been removed in Spring Framework 6.0, immediately replaced by org.apache.httpcomponents.client5:httpclient5 (note: this dependency has a different groupId). If you are noticing issues with HTTP client behavior, it could be that RestTemplate is falling back to the JDK client. org.apache.httpcomponents:httpclient can be brought transitively by other dependencies, so your application might rely on this dependency without declaring it.

https://github.com/spring-projects/spring-framework/issues/28925