1. 序章

プロキシサーバーは、クライアントアプリケーションと他のサーバーの間の仲介役として機能します。 エンタープライズ環境では、通常はネットワークの境界を越えて、ユーザーが消費するコンテンツを制御するためにこれらを使用することがよくあります。

このチュートリアルでは、Javaでプロキシサーバーを介して接続する方法を見ていきます。

最初に、JVM全体で、システムプロパティを使用して構成された、より古く、よりグローバルなアプローチについて説明します。 その後、 Proxy クラスを紹介します。これにより、接続ごとに構成できるようになり、より詳細に制御できるようになります。

2. 設定

この記事のサンプルを実行するには、プロキシサーバーにアクセスする必要があります。 Squid は、ほとんどのオペレーティングシステムで利用できる一般的な実装です。 Squidのデフォルト構成は、ほとんどの例で十分です。

3. グローバル設定の使用

Javaは、JVM全体の動作を構成するために使用できる一連のシステムプロパティを公開します。 この「1つのサイズですべてのアプローチに対応」は、ユースケースに適している場合、実装が最も簡単なことがよくあります。

JVM を呼び出すときに、コマンドラインから必要なプロパティを設定できます。 別の方法として、実行時にSystem.setProperty()を呼び出して設定することもできます

3.1. 利用可能なシステムプロパティ

Javaは、HTTP、HTTPS、FTP、およびSOCKSプロトコルのプロキシハンドラーを提供します。 プロキシは、ハンドラーごとにホスト名とポート番号として定義できます。

  • http.proxyHost –HTTPプロキシサーバーのホスト名
  • http.proxyPort – HTTPプロキシサーバーのポート番号–プロパティはオプションであり、指定されていない場合はデフォルトで80になります
  • http.nonProxyHosts –プロキシをバイパスする必要があるホストパターンのパイプ区切り(「|」)リスト–設定されている場合、HTTPハンドラーとHTTPSハンドラーの両方に適用されます
  • socksProxyHost –SOCKSプロキシサーバーのホスト名
  • socksProxyPort –SOCKSプロキシサーバーのポート番号

nonProxyHosts を指定すると、ホストパターンはワイルドカード文字(「*」)で開始または終了する場合があります。 「|」をエスケープする必要がある場合があります Windowsプラットフォームの区切り文字。 使用可能なすべてのプロキシ関連のシステムプロパティの完全なリストは、Oracleのネットワークプロパティに関する公式Javaドキュメントにあります。

3.2. コマンドライン引数を介して設定

設定をシステムプロパティとして渡すことにより、コマンドラインでプロキシを定義できます。

java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=3128 com.baeldung.networking.proxies.CommandLineProxyDemo

この方法でプロセスを開始すると、追加の作業なしで URLopenConnection()を使用できます。

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の使用

Proxy クラスは、接続ごとにプロキシを構成するための柔軟な方法を提供します。 既存のJVM全体のプロキシ設定がある場合、Proxyクラスを使用した接続ベースのプロキシ設定がそれらを上書きします。

Proxy.Typeで定義できるプロキシには次の3つのタイプがあります。

  • HTTP –HTTPプロトコルを使用するプロキシ
  • SOCKS –SOCKSプロトコルを使用するプロキシ
  • DIRECT –プロキシなしで明示的に構成された直接接続

4.1. HTTPプロキシの使用

HTTPプロキシを使用するには、最初にSocketAddressインスタンスをProxyとタイプProxy.Type.HTTPでラップします。 次に、 Proxyインスタンスを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. ダイレクトプロキシの使用

ホストに直接接続する必要がある場合があります。 この場合、静的Proxy.NO_PROXY インスタンスを使用して、グローバルに構成できるプロキシを明示的にバイパスできます。 裏で、APIは Proxy.Type.DIRECT をタイプとして使用して、Proxyの新しいインスタンスを構築します。

HttpURLConnection directConnection 
  = (HttpURLConnection) weburl.openConnection(Proxy.NO_PROXY);

基本的に、グローバルに構成されたプロキシがない場合、これは引数なしで openConnection()を呼び出すのと同じです。

4.3. SOCKSプロキシの使用

SOCKSプロキシの使用は、 URLConnectionを使用する場合のHTTPバリアントに似ています。まず、Proxy.Type.SOCKSのタイプを使用してSocketAddressインスタンスをプロキシでラップします。 その後、Proxyインスタンスを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にあります。