1.先看出现的问题情况如下:
2.然后我找到了问题的部位是使用httpClient发送请求出现的这个问题,我知道现场使用的是https协议,通过询问现场是否是https协议的证书过期了,但是现场发来如下图:
所以应该是发送https请求时出现了问题;
3.首先,要知道导致报这个异常的原因不仅仅是因为证书校验不通过。在我们通过https链接服务器时,服务器会给我们返回一个证书,这个证书可能经过CA认证,也可能是未认证的自制证书,客户端拿到这个证书后会对这个证书进行验证,如果是经过CA验证的证书,自然证书校验就能通过,自制证书自然就校验不同过,从而导致上边的异常。
证书校验通过后,还需要校验访问的域名是否和证书指定的域名是否匹配。未匹配也会导致如上异常,上边两步都校验通过了才开始进行握手,但握手也有可能失败,从而导致上边的异常。三个步骤中任何一个出了问题,都会报错。
4.我的解决办法如下,亲测有效
a.先创建一个类如下:
package net.newcapec.h5.zsxg.utils;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
public class WebClientDevWrapper {
public static HttpClient wrapClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] arg0,String arg1) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] arg0,String arg1) throws CertificateException {}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", 443, ssf));
ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(registry);
return new DefaultHttpClient(mgr, base.getParams());
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
}
b.在发送请求时使用该类
HttpClient httpclient = new DefaultHttpClient();
httpclient=WebClientDevWrapper.wrapClient(httpclient);
5.此时基本已经可以处理该问题,对于不懂原因的可去查询了解了解。
|