1.简述
使用Https请求知道链接时出现javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure异常,是因为ssl协议错误。
2.解决方案
主要是在创建SSLContext的时候指定TLS协议,就可以解决这个问题,使用的是httpclient-4.5.jar、httpcore-4.4.1.jar。
出现异常示例代码如下:
import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; 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.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.util.EntityUtils; public class Demo { public static void main(String[] args) throws Exception { String url = "https://weather.com/weather/today/l/22.69,113.91?par=google"; String result = ""; CloseableHttpClient httpClient = null; try { SSLContextBuilder builder = new SSLContextBuilder(); // 全部信任 不做身份鉴定 builder.loadTrustMaterial(null, new TrustStrategy() { @Override public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { return true; } }); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), new String[] { "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE); Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", new PlainConnectionSocketFactory()).register("https", sslsf).build(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); cm.setMaxTotal(200);// max connection httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).setConnectionManagerShared(true).build(); HttpGet httpGet = new HttpGet(url); RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();// 设置请求和传输超时时间 httpGet.setConfig(requestConfig); HttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity resEntity = httpResponse.getEntity(); result = EntityUtils.toString(resEntity); } catch (Exception e) { throw e; } finally { if (httpClient != null) { httpClient.close(); } } System.out.println(result); } }