構建https協議的webService並使用httpClient接口訪問

1.組件版本信息
apache-tomcat-7.0.75
JDK 1.8.0_91java

2.使用jdk自帶的keytool命令生成keystore文件test.keystore
命令:keytool -genkey -alias test123 -keypass test123 -keyalg RSA -keysize 1024 -keystore test.keystore -storepass test123web

clipboard.png

3.將test.keystore拷貝到apache-tomcat-7.0.75bin目錄下apache

4.配置tomcat的conf目錄server.xml文件,在配置文件中新增SSL配置tomcat

<Connector SSLEnabled="true" clientAuth="false" keystoreFile="bin/test.keystore" keystorePass="test123" maxThreads="150" port="8443" protocol="org.apache.coyote.http11.Http11Protocol" scheme="https" secure="true" sslProtocol="TLS"/>

5.將webservice工程添加進tomcat並啓動,使用postman訪問http和https連接。http能夠正常訪問,https訪問不了,因爲客戶端證書問題app

clipboard.png

clipboard.png

6.新建類HttpClientTest,用於配置https相關SSL設置maven

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;  
import javax.net.ssl.SSLContext;   
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.ssl.SSLContextBuilder;

public class HttpClientTest
{
    public static CloseableHttpClient createSSLClient()
            throws KeyManagementException, NoSuchAlgorithmException,
            KeyStoreException
    {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(
                null, new TrustStrategy()
                {
                    public boolean isTrusted( X509Certificate[] chain,
                            String authType ) throws CertificateException
                    {
                        return true;
                    }
                } ).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext, NoopHostnameVerifier.INSTANCE );
        return HttpClients.custom().setSSLSocketFactory( sslsf ).build();
    }
}

7.新建類HttpClientUtil,用於測試https的get請求oop

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.logging.Log;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

public class HttpClientUtil
{
    public static void main( String[] args ) throws ClientProtocolException,
            IOException, URISyntaxException, KeyManagementException,
            NoSuchAlgorithmException, KeyStoreException
    {
        String url = "https://localhost:8443/maven-example/hello";
        CloseableHttpClient httpClient = HttpClientTest.createSSLClient();
        HttpGet get = new HttpGet();
        get.setURI( new URI( url ) );
        HttpResponse response = httpClient.execute( get );
        String s = streamToString( response.getEntity().getContent() );
        System.out.println( s );
    }

    private static String streamToString( InputStream is )
            throws IOException
    {

        String line = "";
        StringBuilder total = new StringBuilder();
        BufferedReader rd = new BufferedReader( new InputStreamReader( is ) );
        while ( (line = rd.readLine()) != null )
        {
            total.append( line );
        }
        return total.toString();
    }
}

8.執行main方法,正確輸出https的response響應post

clipboard.png

9.操做過程當中遇到一個問題,報主機名驗證錯誤測試

clipboard.png
解決方法:將new SSLConnectionSocketFactory(sslContext)修改成new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)便可。原理後續進一步研究ui

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext, NoopHostnameVerifier.INSTANCE);
相關文章
相關標籤/搜索