在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客户端三方类库,主要有三步。
- 设置proxy的地址信息
- 设置proxy的鉴权信息
- 如果证书错误,则需要设置sslSocketFactory来处理证书验证。
网友评论