使用httpclient访问https网站时,可能遇到SSLHandshakeException。其根本原因是我们模拟的HttpClient没有SSL证书。
虽然我们可以通过设置Java来解决,但为了保证在各个环境都能正常运行代码,更健壮的方案是忽略掉SSL的检查。
详细代码如下,通过该类获取的CloseableHttpClient,在访问https网站时会自动忽略SSL检查:
package erica.jewels.blackpearl;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
public class SslUtils {
public static CloseableHttpClient SslHttpClientBuild() {
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE).register("https", trustAllHttpsCertificates()).build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
return httpClient;
}
private static SSLConnectionSocketFactory trustAllHttpsCertificates() {
SSLConnectionSocketFactory socketFactory = null;
TrustManager[] trustAllCerts = new TrustManager[1];
TrustManager tm = new miTM();
trustAllCerts[0] = tm;
SSLContext sc = null;
try {
sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, null);
socketFactory = new SSLConnectionSocketFactory(sc, NoopHostnameVerifier.INSTANCE);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return socketFactory;
}
static class miTM implements TrustManager, X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
//don't check
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
//don't check
}
}
}