HttpClient的ssl方式發送請求

最近因爲項目需要,需要以rest方式和第三方平臺交互,由於需要ssl方式連接,所以記錄一下:

maven依賴如下:

        <dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.3</version>
		</dependency>

這裏介紹兩種ssl連接方式,一種是ssl信任所有的證書(基本上也就是沒有安全性保證),另一種是ssl的正常使用(需要證書認證的)
首先是一個工具類

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class HttpsTrustManager implements X509TrustManager {

	@Override
	public void checkClientTrusted(X509Certificate[] arg0, String arg1)
			throws CertificateException {
		// TODO Auto-generated method stub

	}

	@Override
	public void checkServerTrusted(X509Certificate[] arg0, String arg1)
			throws CertificateException {
		// TODO Auto-generated method stub

	}

	@Override
	public X509Certificate[] getAcceptedIssuers() {
		return new X509Certificate[]{};
	}

}

正常SSL方式(需要證書)的工廠類


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.util.Map;

import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
/**
 * 構建httpclient的
 * @author Think
 *
 */
public class HttpClientFactory {

	
		
	private static CloseableHttpClient client;
	
	  /**
     * 獲取需要安全認證的httpClient的實例
     * @Title: getHttpsClient 
     * @Description: TODO
     * @Author: Think
     * @Date :Jan 16, 2019
     * @return: HttpClient
     */
    public static HttpClient getHttpsClient() throws Exception {

        if (client != null) {
            return client;
        }
        SSLContext sslcontext = getSSLContext();
        SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        client = HttpClients.custom().setSSLSocketFactory(factory).build();

        return client;
    }

    private static SSLContext getSSLContext() throws KeyStoreException, 
    NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException {
        KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
        
        String keyLocation = "E:/Java/jre/lib/security/cacerts";//本地cacerts的路徑,一般在jre路徑中
        
        FileInputStream instream = new FileInputStream(new File(keyLocation));
        try {
            trustStore.load(instream, "changeit".toCharArray());
        } finally {
            instream.close();
        }
        return SSLContexts.custom()
                .loadTrustMaterial(trustStore)
                .build();
    }
    
    public static void releaseInstance() {
        client = null;
    }
    
    
}

不安全的SSL方式的工廠類

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class HttpClientFactoryWithNoSSL {

	private static CloseableHttpClient client;
    /**
	 * 獲取不需要ssl認證的httpClient實例
	 * @Title: getHttpsClientWithNoCert 
	 * @Description: TODO
	 * @Author: Think
	 * @Date :Jan 16, 2019
	 * @return: HttpClient
	 */
    public static HttpClient getHttpsClient() throws Exception {

        if (client != null) {
            return client;
        }
        SSLContext sslcontext = SSLContexts.custom().useSSL().build();
        sslcontext.init(null, new X509TrustManager[]{new HttpsTrustManager()}, new SecureRandom());
        SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        client = HttpClients.custom().setSSLSocketFactory(factory).build();

        return client;
    }

    public static void releaseInstance() {
        client = null;
    }
}

使用樣例:

        //獲取httpclient客戶端
    	HttpClient httpsClient = HttpClientFactory.getHttpsClient();
    	//因爲需要認證就是需要將{用戶名:密碼}變成字節數組並base64編碼
		byte[] admin= ParseSSLUtil.getUserTokenString().getBytes();
		String encoding = ParseSSLUtil.encodeBase64(admin);//該工具類方法底層DatatypeConverter.printBase64Binary(input)
		
		
		HttpGet httpGet = new HttpGet(config.get("url").concat("/api/statistics/memoryusage"));
		
		httpGet.addHeader("Content-Type", "application/json");
		httpGet.setHeader("Authorization", "Basic " + encoding);
		String mem = "";
		HttpResponse responseMem = null;
		try {
			responseMem = httpsClient.execute(httpGet);
			if(responseMem.getStatusLine().getStatusCode()!=HttpStatus.SC_OK){
				mem = "0";
			}else if(responseMem.getStatusLine().getStatusCode()==HttpStatus.SC_FORBIDDEN){
				return "error";
			}
			
			HttpEntity entity = responseMem.getEntity();

			if(entity != null){
	            mem = EntityUtils.toString(entity,"UTF-8");
	            EntityUtils.consume(entity);
	        }
		} catch (Exception e1) {
			e1.printStackTrace();
			mem = "0";
		}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章