okhttps及httpClient中的代理设置

在java工程开发过程中,如果需要向外发送网络请求,但是开发过程中网络不通,我们需要通过vpn的方式代理发起请求。又或者需要使用ip池来进行网络爬取,也得通过ip代理来规避ip封禁。

这里,给出了两种常用的http客户端三方类库——OkHttp和HttpClient的代理设置

public class OkHttpUtil {

    private OkHttpClient client;

    private X509TrustManager x509TrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };
    }

    private SSLSocketFactory sslSocketFactory() {
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[] {x509TrustManager()}, new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return null;
    }

    private OkHttpUtil() {
        final String username = "xxx";
        final String password = "yyy";

        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("ipAdress", 8080));

        Authenticator proxyAuthenticator = new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) throws IOException {
                String credential = Credentials.basic(username, password);
                return response.request().newBuilder()
                        .header("Proxy-Authorization", credential)
                        .build();
            }
        };


        client = new OkHttpClient.Builder()
                .addInterceptor(new CommonInterceptor())
                .retryOnConnectionFailure(false)//是否开启缓存
                .connectionPool(pool())//连接池
                .connectTimeout(10L, TimeUnit.SECONDS)
                .readTimeout(10L, TimeUnit.SECONDS)
                .sslSocketFactory(sslSocketFactory(), x509TrustManager())
                .proxy(proxy)
                .proxyAuthenticator(proxyAuthenticator)
                .authenticator(proxyAuthenticator)
                .build();
    }

    // todo 使用client对象进行执行request请求
    // client.newCall(request).execute();
}

相较于正常使用,在build的过程中,设置了proxy及proxyAuthenticator。如果代理过程中ssl或tls相关的错误,则需要加上sslSocketFactory(sslSocketFactory(), x509TrustManager())来处理证书验证,这里默认的处理模式是全部放通,仅用于开发调测阶段。

注:在okhttp3代理设置中,如果通过 java.net.Authenticator.setDefault的方式来设置net全局代理,会报错代理鉴权失败。


        HttpClientBuilder custom = HttpClients.custom();
        
        //设置代理服务器
        HttpHost proxy = new HttpHost("proxy.huawei.com", 8080);
        DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
        custom.setRoutePlanner(routePlanner);

        //设置代理认证
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
                new UsernamePasswordCredentials("账号", "密码"));
        custom.setDefaultCredentialsProvider(credentialsProvider);
        SSLContext sslContext = null;
        try {
            sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy()
            {
                // 信任所有
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
                {
                    return true;
                }
            }).build();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        SSLConnectionSocketFactory sslf = new SSLConnectionSocketFactory(sslContext);
        CloseableHttpClient httpClient = custom.setSSLSocketFactory(sslf).build();


        // todo 使用httpClient对象进行执行request请求
        // httpClient.execute(httpRequest).getEntity()

同理,相较于正常使用,额外设置了proxy的路由及鉴权:custom.setRoutePlanner(routePlanner);custom.setDefaultCredentialsProvider(credentialsProvider);
如果代理过程中ssl或tls相关的错误,则需要通过custom.setSSLSocketFactory来处理证书验证,这里默认的处理模式是全部放通,仅用于开发调测阶段。

总结:
通过http客户端三方类库,主要有三步。

  1. 设置proxy的地址信息
  2. 设置proxy的鉴权信息
  3. 如果证书错误,则需要设置sslSocketFactory来处理证书验证。

你可能感兴趣的:(okhttps及httpClient中的代理设置)