-
Feign 다이나믹하게 proxy 사용하기Java 2022. 4. 13. 09:50반응형
개발을 하다보면 naver.com은 proxy server를 통하고 싶고 google.com은 proxy server를 통하고 싶지 않을 때가 있다. 그러나 보통 System Property로 proxy를 설정하면 전역적으로 proxy가 적용된다. 따라서 다이나믹하게 proxy를 적용할 수 있는 방법을 연구했고 기록을 남긴다.
System Property 사용하기
https://11st-tech.github.io/2021/09/07/proxy-setting-guide/
Feign 동적 proxy 적용
위 게시글에 내용 설명은 자세히 나와있고 내가 적용한 방법을 공유한다.
build.gradle
implementation 'io.github.openfeign:feign-httpclient:10.10.1'
build.gradle에 io.github.openfeign을 추가하지 않으면 DefaultRoutePlanner를 사용하지 않는다.
application.yml
#예시 proxy: url: http://proxy.com:1234 hosts: 'naver.com', 'hanseokhyeon.tistory.com'
application.yml에 proxy를 통해 접근할 url을 proxy.hosts에 지정한다.
CustomProxyRoutePlanner.java
import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.annotation.Contract; import org.apache.http.annotation.ThreadingBehavior; import org.apache.http.conn.SchemePortResolver; import org.apache.http.impl.conn.DefaultRoutePlanner; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL) public class CustomProxyRoutePlanner extends DefaultRoutePlanner { private final HttpHost proxy; private final List<HttpHost> proxyHttpHost; public CustomProxyRoutePlanner(final HttpHost proxy, final SchemePortResolver schemePortResolver, final List<String> proxyURIs) { super(schemePortResolver); this.proxy = Args.notNull(proxy, "Proxy host"); this.proxyHttpHost = proxyURIs.stream() .map(HttpHost::new) .collect(Collectors.toList()); } public CustomProxyRoutePlanner(final HttpHost proxy) { this(proxy, null, Collections.emptyList()); } public CustomProxyRoutePlanner(final HttpHost proxy, final List<String> proxyURIs) { this(proxy, null, proxyURIs); } @Override protected HttpHost determineProxy( final HttpHost target, final HttpRequest request, final HttpContext context) throws HttpException { for (HttpHost httpHost : proxyHttpHost) { if (target.getHostName().equals(httpHost.getHostName())) { return proxy; } } return null; } }
determineProxy 메서드에서 proxy를 통할지 말지 결정한다. 생성자에서 만들어둔 HttpHost 리스트에 같은 hostname을 가진 인스턴스가 있으면 proxy를 return하고 없으면 null을 리턴한다. naver.com은 리스트에 존재하므로 proxy를 return하고 proxy를 통해 접근된다.
CustomHttpClientConfiguration.java
import org.apache.http.HttpHost; import org.apache.http.impl.client.HttpClientBuilder; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.net.MalformedURLException; import java.net.URL; import java.util.List; @Configuration public class CustomHttpClientConfiguration { @Value("${proxy.url}") private String proxyUrl; @Value("${proxy.hosts}") private List<String> proxyHosts; @Bean public HttpClientBuilder apacheHttpClientBuilder() throws MalformedURLException { var proxy = new HttpHost(new URL(proxyUrl).getHost(), new URL(proxyUrl).getPort()); var customRoutePlanner = new CustomProxyRoutePlanner(proxy, proxyHosts); return HttpClientBuilder.create().setRoutePlanner(customRoutePlanner); } }
위에서 작성한 CustomProxyRoutePlanner을 사용할 수 있도록 Builder를 선언하고 Bean으로 등록한다.
반응형'Java' 카테고리의 다른 글
엑셀 업로드 에러 (0) 2023.01.10 ES Json 쿼리 조회 (0) 2022.12.15 Feign 다이나믹 header (0) 2022.04.12 Feign POST 파일 전송 (multipart/form-data) (0) 2022.04.12 Feign POST application/x-www-form-urlencoded (0) 2022.04.12