プロキシのJavaでのHTTPリクエスト


HTTP上のデータへのアクセスは、より一般的です.それはAPIまたはウェブページである、アプリケーション間の相互通信が成長している.ウェブサイトの削り.
JavaでHTTP呼び出しを実行する簡単な組み込みソリューションはありません.多くのパッケージはいくつかの関連した機能を提供します、しかし、それは1つを選ぶのが簡単でありません.特にあなたが認証プロキシ経由で接続するようないくつかの余分な機能が必要な場合.
我々は基本的な要求から高度な機能を使用して行くfluent.Request , の一部Apache HttpComponents プロジェクト

ダイレクトリクエスト


第1ステップは所望のページを要求することである.私たちはhttpbin デモのために.それはヘッダーと起源IPを示します.そして、リクエストが成功したかどうかチェックすることができます.
我々は輸入する必要があるRequest , ターゲットページを取得し、結果を文字列として展開します.パッケージはそれらのケースおよび多くのための方法を提供する.最後にレスポンスを出力します.
import org.apache.hc.client5.http.fluent.Request;

public class TestRequest {
    public static void main(final String... args) throws Exception {
        String url = "http://httpbin.org/anything";

        String response = Request
                .get(url) // use GET HTTP method
                .execute() // perform the call
                .returnContent() // handle and return response
                .asString(); // convert response to string

        System.out.println(response);
    }
}
応答を処理したりエラーをチェックしたりしません.これは実際のユースケースの簡易版です.
しかし、我々は結果が成功したということを見ることができます、そして、我々のIPは起源として示します.我々はすぐにそれを解決します.

プロキシリクエスト


セキュリティや匿名性などのHTTPリクエストにプロキシを追加する理由はたくさんあります.いずれにせよ、Javaライブラリ(通常)プロキシを複雑に追加する.
我々の場合、我々は使用できるviaProxy プロキシのURLを使用すると、認証を必要としない限り.後でそれ以上.
今のところ、無料リストからプロキシを使用します.これらに注意free proxies あなたのために働かないかもしれません.彼らは短時間の生活だ.
import org.apache.hc.client5.http.fluent.Request;

public class TestRequest {
    public static void main(final String... args) throws Exception {
        String url = "http://httpbin.org/anything";
        String proxy = "http://169.57.1.85:8123"; // Free proxy

        String response = Request.get(url)
                .viaProxy(proxy) // will set the passed proxy
                .execute().returnContent().asString();

        System.out.println(response);
    }
}

認証付きプロキシ


有料またはプライベートプロキシプロバイダZenRows - 頻繁に各呼び出しで認証を使用します.時々、それはIP許可されたリストを通してされますProxy-Authorization ヘッダ.
適切なAuthメソッドを使用しないプロキシを呼び出すと、エラーが発生します.Exception in thread "main" org.apache.hc.client5.http.HttpResponseException: status code: 407, reason phrase: Proxy Authentication Required .
次の例では、Authとプロキシをホストとして渡す必要があります.
Proxy-Authorization base 64エンコードされたユーザとパスワードを含みます.
では、どのように変更する必要がありますかviaProxy ユーザとパスワードでURLを許可しないので、プロキシを取得します.そのために、我々は新しいHttpHost URL全体を渡す.それは内部的に問題を処理し、不要な部分を省略します.
import java.net.URI;
import java.util.Base64;

import org.apache.hc.client5.http.fluent.Request;
import org.apache.hc.core5.http.HttpHost;

public class TestRequest {
    public static void main(final String... args) throws Exception {
        String url = "http://httpbin.org/anything";
        URI proxyURI = new URI("http://YOUR_API_KEY:@proxy.zenrows.com:8001"); // Proxy URL as given by the provider
        String basicAuth = new String(
            Base64.getEncoder() // get the base64 encoder
            .encode(
                proxyURI.getUserInfo().getBytes() // get user and password from the proxy URL
            ));
        String response = Request.get(url)
                .addHeader("Proxy-Authorization", "Basic " + basicAuth) // add auth
                .viaProxy(HttpHost.create(proxyURI)) // will set the passed proxy as a host
                .execute().returnContent().asString();

        System.out.println(response);
    }
}

SSL証明書を無視する


SSL(HTTPS)接続にプロキシを追加するとき、ライブラリは、証明書について警告/エラーを発生させる傾向があります.セキュリティの観点から、それは素晴らしいです!私たちは、私たちが避けるのを好むサイトに示されるか、またはリダイレクトされるのを避けます.
しかし、我々自身のプロキシを通して我々の接続を強制することについて?それらの場合にセキュリティリスクはないので、それらの警告を無視したい.つまり、Javaでは簡単なタスクではありません.
エラーは次のようになります.Exception in thread "main" javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target .
この場合、ターゲットURLをhttps . また、次に作成するヘルパーメソッドを呼び出します.メイン関数の変更はありません.
public class TestRequest {
    public static void main(final String... args) throws Exception {
        ignoreCertWarning(); // new method that will ignore certificate warnings

        String url = "https://httpbin.org/anything"; // switch to https
        // ...
    }
}
今、複雑で冗長な部分に.SSLコンテキストと偽の証明書を作成する必要があります.ご覧のように、証明書マネージャとそのメソッドは何もしません.それはちょうど内部の作業を回避し、したがって、問題を回避します.最後に、作成された偽のcertsとコンテキストを初期化し、デフォルトとして設定します.そして、我々は行くのが良いです!
import java.security.cert.X509Certificate;
import javax.net.ssl.*;

public class TestRequest {
    // ...
    private static void ignoreCertWarning() {
        SSLContext ctx = null;
        TrustManager[] trustAllCerts = new X509TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {return null;}
            public void checkClientTrusted(X509Certificate[] certs, String authType) {}
            public void checkServerTrusted(X509Certificate[] certs, String authType) {}
        } };

        try {
            ctx = SSLContext.getInstance("SSL");
            ctx.init(null, trustAllCerts, null);
            SSLContext.setDefault(ctx);
        } catch (Exception e) {}
    }
}

結論


Javaでデータにアクセスするか、複雑にすることができます.しかし、適切なツールとライブラリで、我々はその冗長性を飼うようになりました-しかし、証明書のために.
私たちは将来この話題に戻るかもしれません.HttpComponentライブラリは、asyncやマルチスレッド実行のような魅力的な機能を提供します.