Axis 1.x 編寫的client在測試https的webservice的時候, 因爲client 代碼創建SSL鏈接的時候沒有對truststore進行設置,在與https部署的webservice 鏈接會在運行時報出:java
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targetweb
這是因爲Axis的client用默認的SocketFactory,會對server端的證書進行驗證,咱們的測試server是自簽名的,client檢測到後自動斷開鏈接,握手失敗。dom
網上不少解決方案是用sun的keytool生成clientTrustStore和serverTrustStrore並把證書導進去,這些方法都稍顯繁瑣,咱們這種client測試類不必作一些程序以外的工做,因此綜合了一個解決方案,想到這個辦法。此方法的靈感來自於axis文檔裏的dirty solution。socket
核心思想是本身作一個不對證書作任何檢查的SocketFactory,並用這個socket factory來替換Axis自己用的SocketFactory, 爲了方便,MySocketFactory直接繼承Axis的父類JSSESocketFactory 。而且重寫父類方法ide
protected void initFactory() throws IOException
initFactory方法的內容,很簡單,就是讓checkServerTrusted/checkClientTrusted什麼都不返回,而後最後一行將這個SslSocketFactory賦給咱們自定義類裏的sslFactory變量。測試
// Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { // Trust always } public void checkServerTrusted(X509Certificate[] certs, String authType) { // Trust always } } }; // Install the all-trusting trust manager SSLContext sc = SSLContext.getInstance("SSL"); // Create empty HostnameVerifier HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String arg0, SSLSession arg1) { return true; } }; sc.init(null, trustAllCerts, new java.security.SecureRandom());
sslFactory = sc.getSocketFactory;
Axis client測試類中用ui
AxisProperties.setProperty("axis.socketSecureFactory","my.test.MySocketFactory")來指定Axis類庫要調用的SocketFactory,就是以前被咱們改寫的不對server certificate作任何驗證的Factory。
這個解決方式絕對簡單,不須要跟其餘方式同樣用sun的keytool創建導入一些本地證書,並利用了Axis本身的機制處理證書驗證問題。spa