JVM에서 프록시를 사용하도록 설정하는 방법


307

많은 경우, Java 앱은 인터넷에 연결해야합니다. 가장 일반적인 예는 XML 파일을 읽고 스키마를 다운로드해야 할 때 발생합니다.

프록시 서버 뒤에 있습니다. 프록시를 사용하도록 JVM을 어떻게 설정합니까?


이 문제에 대한 오라클 문서 는 여전히 유효하지 않습니다 (아마도 유효한 것 같습니다). 다음은 Spring에서 더 현대적인 것입니다 : docs.spring.io/spring-integration/reference/html/…
nobar

답변:


350

자바 문서 (에서 하지 javadoc에의 API) :

http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html

JVM이 플래그를 설정 http.proxyHost하고 http.proxyPort명령 행에 JVM을 시작할 때. 일반적으로 쉘 스크립트 (Unix) 또는 bat 파일 (Windows)에서 수행됩니다. 유닉스 쉘 스크립트를 사용한 예는 다음과 같습니다.

JAVA_FLAGS=-Dhttp.proxyHost=10.0.0.100 -Dhttp.proxyPort=8800
java ${JAVA_FLAGS} ...

JBoss 또는 WebLogic과 같은 컨테이너를 사용할 때 솔루션은 공급 업체가 제공 한 시작 스크립트를 편집하는 것입니다.

많은 개발자들이 Java API (javadocs)에 익숙하지만 나머지 문서는 간과되는 경우가 많습니다. 여기에는 많은 흥미로운 정보가 포함되어 있습니다 : http://download.oracle.com/javase/6/docs/technotes/guides/


업데이트 : 프록시를 사용하여 일부 로컬 / 인트라넷 호스트를 확인하지 않으려면 @Tomalak의 주석을 확인하십시오.

또한 http.nonProxyHosts 속성을 잊지 마십시오!

-Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com‌​|etc"

109
+1. 또한 http.nonProxyHosts속성을 잊지 마십시오 ! (이 같은 사용 : -Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com|etc")
Tomalak

3
안녕하세요 여러분, 어떻게 여기에 사용자 이름과 비밀번호를 포함시킬 수 있습니까? 감사합니다
Joeblackdev

8
@Joeblackdev http.proxyUser 및 http.proxyPassword를보십시오
aasukisuki

4
@aasukisuki http.proxyUserhttp.proxyPasswordJava 시스템 등록되지 않습니다. Apache HTTP 클라이언트 용입니다.
Lorne의 후작 2

24
또한 HTTP 를 구성 https.proxyHost하고 구성하는 것을 잊지 마십시오 https.proxyPort.
C-Otto

102

시스템 프록시 설정을 사용하려면 :

java -Djava.net.useSystemProxies=true ...

또는 프로그래밍 방식으로 :

System.setProperty("java.net.useSystemProxies", "true");

출처 : http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html


멋진 설정 jvm 논쟁은 매력처럼 나를 위해 작동합니다. 감사합니다
nanosoft

이 코드를 사용하여 SSLSocket에서 "false"값으로 프록시를 비활성화했습니다. 감사.
Fer

1
아마도 프록시에 인증이 필요하기 때문일 수 있지만 이것이 효과가 없었습니다. 그랬 으면 좋겠다.
Simon Forsberg 9

3
PAC (Proxy Auto-Config) 파일에서는 작동하지 않습니다. stackoverflow.com/questions/10324996/…
Michael_S

80

프로그래밍 방식으로 HTTP / HTTPS 및 / 또는 SOCKS 프록시를 설정하려면

...

public void setProxy() {
    if (isUseHTTPProxy()) {
        // HTTP/HTTPS Proxy
        System.setProperty("http.proxyHost", getHTTPHost());
        System.setProperty("http.proxyPort", getHTTPPort());
        System.setProperty("https.proxyHost", getHTTPHost());
        System.setProperty("https.proxyPort", getHTTPPort());
        if (isUseHTTPAuth()) {
            String encoded = new String(Base64.encodeBase64((getHTTPUsername() + ":" + getHTTPPassword()).getBytes()));
            con.setRequestProperty("Proxy-Authorization", "Basic " + encoded);
            Authenticator.setDefault(new ProxyAuth(getHTTPUsername(), getHTTPPassword()));
        }
    }
    if (isUseSOCKSProxy()) {
        // SOCKS Proxy
        System.setProperty("socksProxyHost", getSOCKSHost());
        System.setProperty("socksProxyPort", getSOCKSPort());
        if (isUseSOCKSAuth()) {
            System.setProperty("java.net.socks.username", getSOCKSUsername());
            System.setProperty("java.net.socks.password", getSOCKSPassword());
            Authenticator.setDefault(new ProxyAuth(getSOCKSUsername(), getSOCKSPassword()));
        }
    }
}

...

public class ProxyAuth extends Authenticator {
    private PasswordAuthentication auth;

    private ProxyAuth(String user, String password) {
        auth = new PasswordAuthentication(user, password == null ? new char[]{} : password.toCharArray());
    }

    protected PasswordAuthentication getPasswordAuthentication() {
        return auth;
    }
}

...

HTTP 프록시와 SOCKS 프록시는 네트워크 스택에서 서로 다른 수준에서 작동하므로 둘 중 하나 또는 둘 다 사용할 수 있습니다.


4
"java.net.socks.username / 암호가"설정되어있는 경우, 그 이유 인증자를 설정?
Lorne의 후작

1
"con.setRequest ..."가 아닌 이유는 무엇입니까? 이를 위해 어떤 라이브러리가 필요합니까?
Randnum

1
때로는 http 프록시가 내 문제를 해결할 수없는 것처럼 양말 프록시 옵션에 +1
manuzhang

1
필자의 테스트에서는 기본 인증 자만 설정하면 인증 속성을 설정할 필요가 없습니다.
Drew Stephens

1
시스템 속성 만 있으면 작동하지 않습니다. java.net.socks. (username | password) 프로퍼티는 아무것도하지 않습니다.
Drew Stephens

46

이러한 방법으로 프로그래밍 방식으로 해당 플래그를 설정할 수 있습니다.

if (needsProxy()) {
    System.setProperty("http.proxyHost",getProxyHost());
    System.setProperty("http.proxyPort",getProxyPort());
} else {
    System.setProperty("http.proxyHost","");
    System.setProperty("http.proxyPort","");
}

그냥 방법에서 올바른 값을 반환 needsProxy(), getProxyHost()그리고 getProxyPort()당신은 당신이 원하는 때마다이 코드를 호출 할 수 있습니다.


34
"proxySet"는 아무것도하지 않습니다. 증명 : "false"로 설정하십시오. JDK에는 그러한 재산이 없었으며, 다양한 서적과 온라인 참조에도 불구하고. 그것은 긴 소멸 HotJavaBean, 캡슐화 된 브라우저에서 온 1998 년 대한의 죽음을
론의 후작

2
실제로 http / https없는 속성 이름은 무엇입니까?
Betlista

18
이것은 세 가지로 잘못되었습니다 : 1 : 언급 한 바와 같이, "proxySet"항목이 없습니다. 2 : "proxyHost"및 "proxyPort"는 "http.proxyHost"및 "http.proxyPort"(또는 'https'에 해당) 여야합니다. 3 : System.getProperties (). put (X, Y)는 하지 System.setProperty를 (X, Y)와 동일. 그 외에는 훌륭한 답변입니다.
Rob Cranfill


1
@RobCranfill 1 : "proxySet"은 예전 JDK에 필요했지만 더 이상 필요하지 않은 비표준 플래그였습니다. 2 : "proxyHost"및 "proxyPort"가 작동합니다 ( "http"). prefix는 HTTP 프로토콜 ( "https"와 유사)로 제한합니다. 3 : 여기가 맞습니다.
toolforger

24

JVM이 프록시를 사용하여 HTTP 호출

System.getProperties().put("http.proxyHost", "someProxyURL");
System.getProperties().put("http.proxyPort", "someProxyPort");

이것은 사용자 설정 프록시를 사용할 수 있습니다

System.setProperty("java.net.useSystemProxies", "true");

System.setProperty대신 사용System.getProperties().put(...)
Simon Forsberg 9

12

프록시 서버에 대한 일부 특성을 jvm 매개 변수로 설정할 수 있습니다

-Dhttp.proxyPort = 8080, proxyHost 등

그러나 인증 프록시를 통과해야하는 경우 다음 예와 같은 인증자가 필요합니다.

ProxyAuthenticator.java

import java.net.*;
import java.io.*;

public class ProxyAuthenticator extends Authenticator {

    private String userName, password;

    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(userName, password.toCharArray());
    }

    public ProxyAuthenticator(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }
}

Example.java

    import java.net.Authenticator;
    import ProxyAuthenticator;

public class Example {

    public static void main(String[] args) {
        String username = System.getProperty("proxy.authentication.username");
        String password = System.getProperty("proxy.authentication.password");

                if (username != null && !username.equals("")) {
            Authenticator.setDefault(new ProxyAuthenticator(username, password));
        }

                // here your JVM will be authenticated

    }
}

이 답글을 기반으로 : http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E


이 작동하지 않습니다. 아직 인증되지 않은 경우 기본 함수의 첫 번째 줄은 많은 null 값을 가져오고 코드가 중지됩니다. 프록시를 통해 URL을 호출 할 수 있도록 누군가가 jvm을 인증하는 데 도움이되지 않습니다.
랜디 넘

12

분류기와 Javabrett / Leonel의 답변 결합 :

java -Dhttp.proxyHost=10.10.10.10 -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password -jar myJar.jar


9

다음은 명령 행에서 프록시 사용자 및 프록시 비밀번호사용 하여 프록시를 Java로 설정하는 방법을 보여줍니다 . 이는 매우 일반적인 경우입니다. 일반적으로 암호와 호스트를 코드에 저장해서는 안됩니다.

명령 행에서 -D를 사용하여 시스템 특성을 전달하고 System.setProperty ( "name", "value")를 사용하여 코드에서 시스템 특성을 설정하는 것은 동일합니다.

그러나 이것을 주목하십시오

작동하는 예 :

C:\temp>java -Dhttps.proxyHost=host -Dhttps.proxyPort=port -Dhttps.proxyUser=user -Dhttps.proxyPassword="password" -Djavax.net.ssl.trustStore=c:/cacerts -Djavax.net.ssl.trustStorePassword=changeit com.andreas.JavaNetHttpConnection

그러나 다음 은 작동하지 않습니다 .

C:\temp>java com.andreas.JavaNetHttpConnection -Dhttps.proxyHost=host -Dhttps.proxyPort=port -Dhttps=proxyUser=user -Dhttps.proxyPassword="password" -Djavax.net.ssl.trustStore=c:/cacerts -Djavax.net.ssl.trustStorePassword=changeit

유일한 차이점은 시스템 속성의 위치입니다! (수업 전후)

비밀번호에 특수 문자가있는 경우 위의 예와 같이 "@ MyPass123 %"를 따옴표로 묶을 수 있습니다.

당신이 HTTPS 서비스에 액세스하는 경우, 당신은 사용해야합니다 https.proxyHost, https.proxyPort

당신이 HTTP 서비스에 액세스하는 경우, 당신은 사용해야합니다 http.proxyHost, http.proxyPort


5
ProxyUser 및 proxyPassword는 Java 시스템 특성이 아니지만 Apache HTTP 클라이언트 특성이므로 모든 경우에 작동하지는 않습니다.
THelper

8

XML 파일을 읽고 스키마를 다운로드해야합니다.

인터넷을 통해 스키마 또는 DTD를 검색 할 경우 속도가 느리고 대화하기 쉽고 취약한 응용 프로그램을 작성하는 것입니다. 파일을 호스팅하는 원격 서버가 계획되거나 계획되지 않은 가동 중지 시간이 걸리면 어떻게됩니까? 앱이 중단되었습니다. 그 확인은?

http://xml.apache.org/commons/components/resolver/resolver-article.html#s.catalog.files를 참조하십시오 .

스키마 등의 URL은 고유 식별자로 가장 잘 생각됩니다. 실제로 해당 파일에 원격으로 액세스하라는 요청이 아닙니다. "XML 카탈로그"에서 Google 검색을 수행하십시오. XML 카탈로그를 사용하면 이러한 리소스를 로컬로 호스팅 할 수있어 속도 저하, 대화 및 취약성을 해결할 수 있습니다.

기본적으로 원격 컨텐츠의 영구적으로 캐시 된 사본입니다. 원격 콘텐츠는 절대 바뀌지 않기 때문에 괜찮습니다. 업데이트가있는 경우 다른 URL에있을 것입니다. 인터넷을 통한 자원의 실제 검색은 특히 어리 석습니다.


7

나는 또한 방화벽 뒤에있다, 이것은 나를 위해 일했다!!

System.setProperty("http.proxyHost", "proxy host addr");
System.setProperty("http.proxyPort", "808");
Authenticator.setDefault(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {

        return new PasswordAuthentication("domain\\user","password".toCharArray());
    }
});

URL url = new URL("http://www.google.com/");
URLConnection con = url.openConnection();

BufferedReader in = new BufferedReader(new InputStreamReader(
                    con.getInputStream()));

// Read it ...
String inputLine;
while ((inputLine = in.readLine()) != null)
    System.out.println(inputLine);

in.close();

5

"Socks Proxy"를 원하는 경우 "socksProxyHost"및 "socksProxyPort"VM 인수를 알려주십시오.

예 :

java -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8080 org.example.Main

4

프록시 뒤의 URL에 연결하기 전에이를 추가하십시오.

System.getProperties().put("http.proxyHost", "someProxyURL");
System.getProperties().put("http.proxyPort", "someProxyPort");
System.getProperties().put("http.proxyUser", "someUserName");
System.getProperties().put("http.proxyPassword", "somePassword");

4
http.proxyUserhttp.proxyPasswordJava 시스템 등록되지 않습니다. Apache HTTP 클라이언트 용입니다.
Lorne의 후작 2

System.setProperty대신 사용System.getProperties().put(...)
Simon Forsberg

4

이것은 사소한 업데이트이지만 Java 7부터 시스템 속성을 통하지 않고 프로그래밍 방식으로 프록시 연결을 만들 수 있습니다. 다음과 같은 경우에 유용 할 수 있습니다.

  1. 프로그램 실행 중 프록시를 동적으로 회전해야합니다.
  2. 여러 개의 병렬 프록시를 사용해야합니다
  3. 또는 코드를 더 깨끗하게 만드십시오 :)

다음은 그루비에서 고안된 예입니다.

// proxy configuration read from file resource under "proxyFileName"
String proxyFileName = "proxy.txt"
String proxyPort = "1234"
String url = "http://www.promised.land"
File testProxyFile = new File(proxyFileName)
URLConnection connection

if (!testProxyFile.exists()) {

    logger.debug "proxyFileName doesn't exist.  Bypassing connection via proxy."
    connection = url.toURL().openConnection()

} else {
    String proxyAddress = testProxyFile.text
    connection = url.toURL().openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, proxyPort)))
}

try {
    connection.connect()
}
catch (Exception e) {
    logger.error e.printStackTrace()
}

전체 참조 : http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html


2
이것은 1.7이 아닌 Java 1.5 이후입니다.
Lorne의 후작 2

3

최근에 JVM이 브라우저 프록시 설정을 사용하도록 허용하는 방법을 발견했습니다. ${java.home}/lib/deploy.jar프로젝트 에 추가 하고 다음과 같이 라이브러리를 초기화해야합니다.

import com.sun.deploy.net.proxy.DeployProxySelector;
import com.sun.deploy.services.PlatformType;
import com.sun.deploy.services.ServiceManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public abstract class ExtendedProxyManager {

    private static final Log logger = LogFactory.getLog(ExtendedProxyManager.class);

    /**
     * After calling this method, proxy settings can be magically retrieved from default browser settings.
     */
    public static boolean init() {
        logger.debug("Init started");

        // Initialization code was taken from com.sun.deploy.ClientContainer:
        ServiceManager
                .setService(System.getProperty("os.name").toLowerCase().indexOf("windows") != -1 ? PlatformType.STANDALONE_TIGER_WIN32
                        : PlatformType.STANDALONE_TIGER_UNIX);

        try {
            // This will call ProxySelector.setDefault():
            DeployProxySelector.reset();
        } catch (Throwable throwable) {
            logger.error("Unable to initialize extended dynamic browser proxy settings support.", throwable);

            return false;
        }

        return true;
    }
}

그런 다음를 통해 Java API에서 프록시 설정을 사용할 수 있습니다 java.net.ProxySelector.

이 접근법의 유일한 문제점 deploy.jar은 bootclasspath에서 JVM을 시작해야한다는 것 java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar입니다. 누군가이 제한을 극복하는 방법을 알고 있다면 알려주십시오.


1
나는 이것을 여러 번 공표 할 수 있었으면 좋겠다. 그것이 나를 위해 일한 유일한 해결책이다. 감사합니다! 여기에서 Apache Commons Logging Jar를 다운로드해야했습니다. commons.apache.org/proper/commons-logging/download_logging.cgi Main ()의 내 코드 : System.setProperty ( "java.net.useSystemProxies", "true") ; System.out.println ( "프록시 감지"); ExtendedProxyManager.init ();
보리스

xbootclasspathdeploy.jar을 가리키는 것은 어떤 효과가 있습니까? 웹 항아리없이 실행할 때 해당 항아리를 일반 클래스 경로로 가져올 수 없습니까?
호우 트먼

1
JDK 9에서는 실패합니다 :( Exception in thread "main" java.lang.IllegalAccessError: class ...) cannot access class com.sun.deploy.net.proxy.DeployProxySelector (in module jdk.deploy) because module jdk.deploy does not export com.sun.deploy.net.proxy
Houtman

2

그것은 나를 위해 작동합니다 :

public void setHttpProxy(boolean isNeedProxy) {
    if (isNeedProxy) {
        System.setProperty("http.proxyHost", getProxyHost());
        System.setProperty("http.proxyPort", getProxyPort());
    } else {
        System.clearProperty("http.proxyHost");
        System.clearProperty("http.proxyPort");
    }
}

추신 : 나는 GHad의 대답에 기초합니다.


이 답변은 다른 답변에서 아직 언급되지 않은 내용은 제공하지 않습니다.
Simon Forsberg 9

1

다른 답변에서 지적했듯이 인증 된 프록시를 사용해야하는 경우 명령 줄 변수를 사용하여 순수 하게이 작업을 수행 할 수있는 신뢰할 수있는 방법은 없습니다-다른 사람의 응용 프로그램을 사용하고 있고 소스 코드.

Will IversonHttpProxy를 사용하여 사전 인증을 통해 호스트에 연결하여 Proxifier ( Mac OS X 및 Windows의 경우 http://www.proxifier.com/) 와 같은 프록시 관리 도구를 사용하여이를 처리 하는 데 유용한 제안을 합니다.

예를 들어 Proxifier를 사용하면 (인증 된) 프록시를 통해 관리되고 리디렉션되는 java 명령 만 가로 채도록 설정할 수 있습니다. 이 경우 proxyHost 및 proxyPort 값을 공백으로 설정하려고합니다 (예 : -Dhttp.proxyHost= -Dhttp.proxyPort=java 명령에 전달) .


-1

독립형 JVM 내에 있지만 시작 스크립트를 수정하거나 응용 프로그램 서버 내에서 (jboss 또는 tomcat 제외) 수행하지 않으면 http.proxy * JVM 변수를 활용할 수 있습니다. 대신 JAVA 프록시 API (System.setProperty가 아님)를 사용하거나 공급 업체 고유의 구성 옵션을 사용해야합니다. WebSphere와 WebLogic 모두 J2SE보다 훨씬 강력한 프록시 설정 방법을 정의했습니다. 또한 WebSphere 및 WebLogic의 경우 시작 스크립트 (특히 프록시를 사용하도록 지시 할 때 서버의 interop 프로세스를 무시 함)를 대체하여 응용 프로그램 서버를 작은 방식으로 중단 할 수 있습니다.


-5

나는 구성 생각 WINHTTP 도 효과가 .

Windows Update를 포함한 많은 프로그램이 프록시 뒤에 문제가 있습니다. WINHTTP를 설정하면 항상 이런 종류의 문제가 해결됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.