httpclient 3.1跳过https请求SSL的验证
Posted MokeyChan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了httpclient 3.1跳过https请求SSL的验证相关的知识,希望对你有一定的参考价值。
一、因为在使用https发送请求的时候会涉及,验证方式。但是这种方式在使用的时候很不方便。特别是在请求外部接口的时候,所以这我写了一个跳过验证的方式。(供参考)
二、加入包,这里用的是commons-httpclient 3.1 的包。一般请求采用最新的httpclient4.5就可以了
<dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency>
三、这里我们实现3个类
1、MyX509TrustManager(这个方法直接实现X509TrustManager,X509TrustManager在javax.net.ssl.X509TrustManager里面)
这里直接实现不用改任何东西
import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; public class MyX509TrustManager implements X509TrustManager { /* (non-Javadoc) * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String) */ public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } /* (non-Javadoc) * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String) */ public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } /* (non-Javadoc) * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() */ public X509Certificate[] getAcceptedIssuers() { return null; } }
2、MySecureProtocolSocketFactory(这里我们需要用到SSLContext,还需要改写一个实现SecureProtocolSocketFactory的方法)
import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.HttpClientError; import org.apache.commons.httpclient.params.HttpConnectionParams; import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory; import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory { //这里添加一个属性,主要目的就是来获取ssl跳过验证 private SSLContext sslContext = null; /** * Constructor for MySecureProtocolSocketFactory. */ public MySecureProtocolSocketFactory() { } /** * 这个创建一个获取SSLContext的方法,导入MyX509TrustManager进行初始化 * @return */ private static SSLContext createEasySSLContext() { try { SSLContext context = SSLContext.getInstance("SSL"); context.init(null, new TrustManager[] { new MyX509TrustManager() }, null); return context; } catch (Exception e) { throw new HttpClientError(e.toString()); } } /** * 判断获取SSLContext * @return */ private SSLContext getSSLContext() { if (this.sslContext == null) { this.sslContext = createEasySSLContext(); } return this.sslContext; } //后面的方法基本上就是带入相关参数就可以了 /* * (non-Javadoc) * * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String, * int, java.net.InetAddress, int) */ public Socket createSocket(String host, int port, InetAddress clientHost,int clientPort) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port,clientHost, clientPort); } /* * (non-Javadoc) * * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String, * int, java.net.InetAddress, int, * org.apache.commons.httpclient.params.HttpConnectionParams) */ public Socket createSocket(final String host, final int port,final InetAddress localAddress, final int localPort, final HttpConnectionParams params) throws IOException,UnknownHostException, ConnectTimeoutException { if (params == null) { throw new IllegalArgumentException("Parameters may not be null"); } int timeout = params.getConnectionTimeout(); if (timeout == 0) { return createSocket(host, port, localAddress, localPort); } else { return ControllerThreadSocketFactory.createSocket(this, host, port,localAddress, localPort, timeout); } } /* * (non-Javadoc) * * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) */ public Socket createSocket(String host, int port) throws IOException,UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port); } /* * (non-Javadoc) * * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) */ public Socket createSocket(Socket socket, String host, int port,boolean autoClose) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(socket, host,port, autoClose); } }
3、然后就是httpclient了,这里实现的方式很单间了,只要声明MySecureProtocolSocketFactory加入就可以了Protocol
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; /* * 利用HttpClient进行post请求的工具类 */ public class HttpClientUtil { public static String doGet(String url) throws Exception { //声明 ProtocolSocketFactory fcty = new MySecureProtocolSocketFactory(); //加入相关的https请求方式 Protocol.registerProtocol("https", new Protocol("https", fcty, 443)); //发送请求即可 org.apache.commons.httpclient.HttpClient httpclient = new org.apache.commons.httpclient.HttpClient(); GetMethod httpget = new GetMethod(url); System.out.println("======url:" + url); try { httpclient.executeMethod(httpget); return httpget.getResponseBodyAsString(); } catch (Exception ex) { ex.printStackTrace(); throw new Exception(ex.getMessage()); } finally { httpget.releaseConnection(); } } }
四、这里基本上就完成了,在会用的时候只要声明MySecureProtocolSocketFactory加入就可以了Protocol,然后就可以实现验证的跳过过了
以上是关于httpclient 3.1跳过https请求SSL的验证的主要内容,如果未能解决你的问题,请参考以下文章
Net Core 3.1 IHttpClientFactory/HttpClient 第一次请求慢
Apache HttpClient 4.3.1 中使用 HTTP 隧道/HTTPS 连接的抢先式代理身份验证
.NET 3.1 中来自 HTTPClient 的 SendAsync 中的对象循环 Json