JVM で使用されるプロキシを設定するにはどうすればよいですか
質問
多くの場合、Java アプリはインターネットに接続する必要があります。最も一般的な例は、XML ファイルを読み取り、そのスキーマをダウンロードする必要がある場合に発生します。
私はプロキシサーバーの背後にいます。プロキシを使用するように JVM を設定するにはどうすればよいですか?
解決
Java ドキュメントから (ない javadoc API):
http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
JVM フラグを設定する http.proxyHost
そして http.proxyPort
コマンドラインで JVM を起動するとき。これは通常、シェル スクリプト (Unix の場合) またはバット ファイル (Windows の場合) で行われます。Unix シェル スクリプトの例を次に示します。
JAVA_FLAGS=-Dhttp.proxyHost=10.0.0.100 -Dhttp.proxyPort=8800
java ${JAVA_FLAGS} ...
JBoss や WebLogic などのコンテナを使用する場合、私の解決策は、ベンダーが提供する起動スクリプトを編集することです。
多くの開発者は Java API (javadoc) に精通していますが、多くの場合、ドキュメントの残りの部分は見落とされています。興味深い情報がたくさん含まれています。 http://download.oracle.com/javase/6/docs/technotes/guides/
アップデート : 一部のローカル/イントラネット ホストを解決するためにプロキシを使用したくない場合は、@Tomalak からのコメントを確認してください。
http.nonProxyHosts プロパティも忘れないでください。
-Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com|etc"
他のヒント
システムプロキシ設定を使用するには:
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
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 プロキシはネットワーク スタックの異なるレベルで動作するため、どちらか一方、または両方を使用できることに注意してください。
次の方法でこれらのフラグをプログラムで設定できます。
if (needsProxy()) {
System.setProperty("http.proxyHost",getProxyHost());
System.setProperty("http.proxyPort",getProxyPort());
} else {
System.setProperty("http.proxyHost","");
System.setProperty("http.proxyPort","");
}
メソッドから正しい値を返すだけです needsProxy()
, getProxyHost()
そして getProxyPort()
このコード スニペットはいつでも呼び出すことができます。
JVM はプロキシを使用して HTTP 呼び出しを行います
System.getProperties().put("http.proxyHost", "someProxyURL");
System.getProperties().put("http.proxyPort", "someProxyPort");
これはユーザー設定プロキシを使用する可能性があります
System.setProperty("java.net.useSystemProxies", "true");
プロキシサーバーに関するいくつかのプロパティを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;
}
}
例.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
Sorter の回答と javabrett/Leonel の回答を組み合わせると、次のようになります。
java -Dhttp.proxyHost=10.10.10.10 -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password -jar myJar.jar
XML ファイルを読み取り、そのスキーマをダウンロードする必要がある
インターネット経由でスキーマや DTD を取得することを期待している場合は、遅く、おしゃべりで、壊れやすいアプリケーションを構築していることになります。ファイルをホストしているリモート サーバーに計画的または計画外のダウンタイムが発生した場合はどうなりますか?アプリが壊れてしまいます。それは大丈夫ですか?
見る http://xml.apache.org/commons/components/resolver/resolver-article.html#s.catalog.files
スキーマなどの URL は、一意の識別子であると考えるのが最も適切です。実際にそのファイルにリモートでアクセスするためのリクエストとしてではありません。「XML カタログ」で Google 検索してください。XML カタログを使用すると、そのようなリソースをローカルでホストできるため、速度の遅さ、おしゃべりさ、脆弱性が解決されます。
これは基本的に、リモート コンテンツの永続的にキャッシュされたコピーです。リモートのコンテンツは決して変更されないため、問題ありません。更新がある場合は、別の URL に更新される可能性があります。インターネット経由で実際にリソースを取得することは、特に愚かなことになります。
をセットする java.net.useSystemProxies
財産を true
. 。たとえば、次のように設定できます。 JAVA_TOOL_OPTIONS 環境変数。Ubuntu では、たとえば次の行を追加できます。 .bashrc
:
import JAVA_TOOL_OPTIONS+=" -Djava.net.useSystemProxies=true"
私もファイアウォールの内側にいますが、これは私にとってはうまくいきました!!
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();
以下は、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 などを使用する必要があります。
プロキシの背後にある 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");
これはマイナーなアップデートですが、Java 7 以降では、システム プロパティを使用するのではなく、プログラムによってプロキシ接続を作成できるようになりました。これは次のような場合に役立つ可能性があります。
- プロキシはプログラムの実行中に動的にローテーションする必要がある
- 複数の並列プロキシを使用する必要がある
- または、単にコードをきれいにするだけです:)
Groovy の不自然な例を次に示します。
// 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
「Socks Proxy」が必要な場合は、「socksProxyHost」および「socksProxyPort」VM 引数を指定します。
例えば
java -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8080 org.example.Main
最近、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
.
このアプローチの唯一の問題は、JVM を起動する必要があることです。 deploy.jar
ブートクラスパス内、例: java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar
. 。誰かがこの制限を克服する方法を知っている場合は、私に知らせてください。
それは私にとってはうまくいきます:
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の答えに基づいています。
他の回答で指摘されているように、認証されたプロキシを使用する必要がある場合、純粋にコマンドライン変数を使用してこれを行う信頼できる方法はありません。他の人のアプリケーションを使用していて、ソースコード。
ウィル・アイバーソン で役に立つ提案をします HttpProxy を使用してプリエンティブ認証でホストに接続する Proxifier ( http://www.proxifier.com/ Mac OS X および Windows の場合) を使用してこれを処理します。
たとえば、Proxifier を使用すると、(認証された) プロキシを通じて管理およびリダイレクトされる Java コマンドのみをインターセプトするように設定できます。ただし、この場合、proxyHost と proxyPort の値を空白に設定する必要があります。通ります -Dhttp.proxyHost= -Dhttp.proxyPort=
Javaコマンドに。
また、常に同じスキーマをダウンロードしたい場合は、クラスパス (ファイルシステムまたは JAR) にスキーマを追加し、カスタム エンティティリゾルバー
見る ここ このアプローチについてさらに詳しく説明します。
編集:見る @me.yahoo.com/a/0QMxE さん EntityResolver アプローチを使用する CatalogResolver についての説明:
CatalogResolver cr = new CatalogResolver();
...
yourParser.setEntityResolver(cr)
スタンドアロン JVM 内にいる場合は http.proxy* JVM 変数を利用できますが、起動スクリプトを変更したり、アプリケーション サーバー内でこれを実行したりしてはなりません (jboss または tomcat を除く)。代わりに、JAVA プロキシ API (System.setProperty ではない) を利用するか、ベンダー独自の構成オプションを利用する必要があります。WebSphere と WebLogic はどちらも、J2SE よりもはるかに強力なプロキシを設定する明確な方法を持っています。さらに、WebSphere と WebLogic の場合、起動スクリプトをオーバーライドすることで、アプリケーション サーバーを少しずつ壊す可能性があります (特にサーバーの相互運用プロセスは、プロキシも使用するように指示している可能性があります...)。
構成すると思います WINHTTP も機能します。
Windows Update を含む多くのプログラムで、プロキシの背後で問題が発生しています。WINHTTP を設定すると、この種の問題は常に解決されます