1. 소개
프록시 서버는 클라이언트 응용 프로그램과 다른 서버 간의 중개자 역할을 합니다. 기업 환경에서 우리는 일반적으로 네트워크 경계를 넘어 사용자가 소비하는 콘텐츠에 대한 제어를 제공하기 위해 이를 사용합니다.
이 사용방법(예제)에서는 Java에서 프록시 서버를 통해 연결하는 방법을 살펴보겠습니다 .
먼저 JVM 전체에 적용되고 시스템 속성으로 구성된 이전의 보다 글로벌한 접근 방식을 살펴보겠습니다. 그런 다음 연결별로 구성을 허용하여 더 많은 제어 기능을 제공 하는 Proxy 클래스를 소개합니다.
2. 설정
이 문서의 샘플을 실행하려면 프록시 서버에 액세스해야 합니다. Squid 는 대부분의 운영 체제에서 사용할 수 있는 대중적인 구현입니다. Squid의 기본 구성은 대부분의 예제에 적합합니다.
3. 전역 설정 사용
Java는 JVM 전체 동작을 구성하는 데 사용할 수 있는 시스템 속성 집합을 노출합니다. 이 "모든 접근 방식에 맞는 하나의 크기"는 사용 사례에 적합할 경우 구현하기 가장 간단한 경우가 많습니다.
JVM을 호출할 때 명령줄에서 필수 속성을 설정할 수 있습니다 . 또는 런타임에 System.setProperty() 를 호출하여 설정할 수도 있습니다 .
3.1. 사용 가능한 시스템 속성
Java는 HTTP, HTTPS, FTP 및 SOCKS 프로토콜에 대한 프록시 핸들러를 제공합니다. 호스트 이름과 포트 번호로 각 핸들러에 대해 프록시를 정의할 수 있습니다.
- http.proxyHost – HTTP 프록시 서버의 호스트 이름
- http.proxyPort – HTTP 프록시 서버의 포트 번호 – 속성은 선택 사항이며 제공되지 않은 경우 기본값은 80입니다.
- http.nonProxyHosts – 프록시를 우회해야 하는 호스트 패턴의 파이프로 구분된(“|”) List – 설정된 경우 HTTP 및 HTTPS 핸들러 모두에 적용
- socksProxyHost – SOCKS 프록시 서버의 호스트 이름
- socksProxyPort – SOCKS 프록시 서버의 포트 번호
nonProxyHosts 를 지정 하면 호스트 패턴이 와일드카드 문자("*")로 시작하거나 끝날 수 있습니다. "|"를 이스케이프해야 할 수도 있습니다. Windows 플랫폼의 구분 기호. 사용 가능한 모든 프록시 관련 시스템 속성의 전체 List은 네트워킹 속성에 대한 Oracle의 공식 Java 설명서에서 찾을 수 있습니다 .
3.2. 명령줄 인수를 통해 설정
설정을 시스템 속성으로 전달하여 명령줄에서 프록시를 정의할 수 있습니다.
java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=3128 com.baeldung.networking.proxies.CommandLineProxyDemo
이 방법으로 프로세스를 시작할 때 추가 작업 없이 URL 에서 openConnection() 을 간단히 사용할 수 있습니다.
URL url = new URL(RESOURCE_URL);
URLConnection con = url.openConnection();
3.3. System.setProperty(String, String) 를 사용하여 설정
명령줄에서 프록시 속성을 설정할 수 없는 경우 프로그램 내 에서 System.setProperty() 를 호출하여 설정할 수 있습니다.
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "3128");
URL url = new URL(RESOURCE_URL);
URLConnection con = url.openConnection();
// ...
나중에 관련 시스템 속성을 수동으로 설정 해제하면 프록시가 더 이상 사용되지 않습니다.
System.setProperty("http.proxyHost", null);
3.4. 전역 구성의 제한 사항
시스템 속성과 함께 전역 구성을 사용하는 것은 구현하기 쉽지만 이 접근 방식 은 설정이 전체 JVM에 적용되기 때문에 수행할 수 있는 작업을 제한합니다 . 이러한 이유로 특정 프로토콜에 대해 정의된 설정은 JVM의 수명 동안 또는 설정이 해제될 때까지 활성화됩니다.
이 제한을 해결하기 위해 필요에 따라 설정을 켜고 끄고 싶을 수 있습니다. 다중 스레드 프로그램에서 이를 안전하게 수행하려면 동시성 문제로부터 보호하는 조치를 도입해야 합니다.
대안으로 프록시 API는 프록시 구성에 대한 보다 세부적인 제어를 제공합니다.
4. 프록시 API 사용
프록시 클래스 는 연결별로 프록시를 구성하는 유연한 방법을 제공합니다. 기존 JVM 전체 프록시 설정이 있는 경우 Proxy 클래스를 사용하는 연결 기반 프록시 설정 이 이를 재정의합니다.
Proxy.Type 으로 정의할 수 있는 세 가지 유형의 프록시가 있습니다 .
- HTTP – HTTP 프로토콜을 사용하는 프록시
- SOCKS – SOCKS 프로토콜을 사용하는 프록시
- DIRECT – 프록시 없이 명시적으로 구성된 직접 연결
4.1. HTTP 프록시 사용
HTTP 프록시를 사용하려면 먼저 SocketAddress 인스턴스를 Proxy 및 Proxy.Type.HTTP 유형으로 래핑 합니다. 다음으로 프록시 인스턴스를 URLConnection.openConnection()에 전달하기만 하면 됩니다.
URL weburl = new URL(URL_STRING);
Proxy webProxy
= new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3128));
HttpURLConnection webProxyConnection
= (HttpURLConnection) weburl.openConnection(webProxy);
간단히 말해 URL_STRING 에 연결한 다음 127.0.0.1:3128 에서 호스트되는 프록시 서버를 통해 해당 연결을 라우팅한다는 의미입니다 .
4.2. DIRECT 프록시 사용
호스트에 직접 연결해야 하는 요구 사항이 있을 수 있습니다. 이 경우 정적 Proxy.NO_PROXY 인스턴스 를 사용하여 전역적으로 구성할 수 있는 프록시를 명시적으로 우회할 수 있습니다. 내부적으로 API는 Proxy.Type.DIRECT 를 유형으로 사용하여 프록시 의 새 인스턴스를 생성 합니다 .
HttpURLConnection directConnection
= (HttpURLConnection) weburl.openConnection(Proxy.NO_PROXY);
기본적으로 전역적으로 구성된 프록시 가 없으면 인수 없이 openConnection() 을 호출하는 것과 같습니다 .
4.3. SOCKS 프록시 사용
SOCKS 프록시를 사용하는 것은 URLConnection 으로 작업할 때 HTTP 변형과 유사합니다 . Proxy.Type.SOCKS 유형을 사용하여 Proxy 로 SocketAddress 인스턴스를 래핑하는 것으로 시작합니다 . 그런 다음 프록시 인스턴스를 URLConnection.openConnection 에 전달합니다 .
Proxy socksProxy
= new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1080));
HttpURLConnection socksConnection
= (HttpURLConnection) weburl.openConnection(socksProxy);
TCP 소켓에 연결할 때 SOCKS 프록시 를 사용할 수도 있습니다 . 먼저 Proxy 인스턴스를 사용하여 Socket 을 구성합니다 . 그런 다음 대상 SocketAddress 인스턴스를 Socket.connect() 에 전달합니다 .
Socket proxySocket = new Socket(socksProxy);
InetSocketAddress socketHost
= new InetSocketAddress(SOCKET_SERVER_HOST, SOCKET_SERVER_PORT);
proxySocket.connect(socketHost);
5. 결론
이 기사에서는 코어 Java에서 프록시 서버로 작업하는 방법을 살펴보았습니다.
먼저, 시스템 속성을 사용하여 프록시 서버를 통해 연결하는 이전의 보다 글로벌한 스타일을 살펴보았습니다. 그런 다음 프록시 서버를 통해 연결할 때 세밀한 제어를 제공 하는 Proxy 클래스 를 사용하는 방법을 살펴보았습니다 .
항상 그렇듯이 이 기사에 사용된 모든 소스 코드는 GitHub 에서 찾을 수 있습니다 .