最近因爲項目需要,需要以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";
}