본문 바로가기
spring

[SpringBoot3] RestTemplate (httpclient 4 → 5) 마이그레이션

by moonsiri 2024. 5. 7.
728x90
반응형

스프링 프레임워크 6.0에서 Apache HttpClient에 대한 지원이 제거되어, org.apache.httpcomponents.client5:httpclient5로 대체되었습니다.

 

1. Maven Dependency 변경

<!-- AS-IS -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

<!-- TO-BE -->
<dependency>
	<groupId>org.apache.httpcomponents.client5</groupId>
	<artifactId>httpclient5</artifactId>
</dependency>

 

2. RestTemplate 마이그레이션

공식 문서를 보고 변경하는 것이 좋습니다.

HttpComponentsClientHttpRequestFactory 클래스로 readTimeout과 connectTimeout을 설정하던 코드가 HttpClientConnectionManager 클래스를 통해 timeout 관련 설정 후 이를 HttpClient에 주입하여 설정하도록 변경되었습니다.

 

AS-IS)

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;

@Configuration
public class RestTemplateConfiguration {

	@Bean
	public RestTemplate commonRestTemplate() {

		RestTemplate restTemplate = new RestTemplate();

		HttpComponentsClientHttpRequestFactory crf = new HttpComponentsClientHttpRequestFactory();
		crf.setReadTimeout(5000); //읽기시간초과 타임아웃
		crf.setConnectTimeout(3000); //연결시간초과 타임아웃

		HttpClient httpClient = HttpClientBuilder.create()
			.setMaxConnTotal(100) //커넥션풀적용(최대 오픈되는 커넥션 수)
			.setMaxConnPerRoute(10) //커넥션풀적용(IP:포트 1쌍에 대해 수행 할 연결 수제한)
			.evictIdleConnections(1000L, TimeUnit.MILLISECONDS) //서버에서 keepalive시간동안 미 사용한 커넥션을 죽이는 등의 케이스 방어로 idle커넥션을 주기적으로 지움
			.build();
            
		crf.setHttpClient(httpClient);

		restTemplate.setRequestFactory(crf);

		return restTemplate;
	}
}

 

TO-BE)

import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.core5.util.TimeValue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;

@Configuration
public class RestTemplateConfiguration {

	@Bean
	public RestTemplate commonRestTemplate() {

		RestTemplate restTemplate = new RestTemplate();

		HttpComponentsClientHttpRequestFactory crf = new HttpComponentsClientHttpRequestFactory();

		HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
			.setDefaultConnectionConfig(ConnectionConfig.custom()
					.setSocketTimeout(5, TimeUnit.SECONDS) //읽기시간초과 타임아웃
					.setConnectTimeout(3, TimeUnit.SECONDS) //연결시간초과 타임아웃
				.build())
			.setMaxConnTotal(100) //커넥션풀적용(최대 오픈되는 커넥션 수)
			.setMaxConnPerRoute(10) //커넥션풀적용(IP:포트 1쌍에 대해 수행 할 연결 수제한)
			.build();

		HttpClient httpClient = HttpClientBuilder.create()
			.setConnectionManager(connectionManager)
			.evictIdleConnections(TimeValue.of(10, TimeUnit.SECONDS)) //서버에서 keepalive시간동안 미 사용한 커넥션을 죽이는 등의 케이스 방어로 idle커넥션을 주기적으로 지움
			.build();

		crf.setHttpClient(httpClient);

		restTemplate.setRequestFactory(crf);

		return restTemplate;
	}
}

 

 

 

[Reference]

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide#apache-httpclient-in-resttemplate

https://hc.apache.org/httpcomponents-client-5.3.x/migration-guide/preparation.html

728x90
반응형

댓글