Java HttpClient如何帶證書發起請求
阿新 • • 發佈:2021-02-04
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 target
at sun.security.ssl.Alerts.getSSLException (Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
at sun.security. ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
at sun.security.ssl.SSLSocketImpl. performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
如果我們在開發中使用HttpClient遇到了上面的錯誤,說明對方的介面需要特定的證書才能請求,那麼如何在HttpClient請求中加入證書呢?
請看下面的程式碼
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
/**
* @author niudali
* @date 2021/2/3 11:16
* @desc
*/
public class HttpUtil {
private static SSLContext sslContext = null;
private static HttpClient httpClient = new DefaultHttpClient();
private static String siteUrl = "";
private static String KEY_STORE_CLIENT_PATH = "";
private static String KEY_STORE_TRUST_PATH = "";
private static String KEY_STORE_PASSWORD = "";
/**
* @param _siteUrl
* @param p12Path .p12檔案地址
* @param trustPath .truststore檔案地址
* @param password 金鑰密碼
*/
public static void init(String _siteUrl, String p12Path, String trustPath, String password) {
try {
siteUrl = _siteUrl;
KEY_STORE_CLIENT_PATH = p12Path;
KEY_STORE_TRUST_PATH = trustPath;
KEY_STORE_PASSWORD = password;
//設定環境變數
System.setProperty("javax.net.ssl.keyStore", KEY_STORE_CLIENT_PATH);
System.setProperty("javax.net.ssl.keyStorePassword", KEY_STORE_PASSWORD);
System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
System.setProperty("javax.net.ssl.trustStore", KEY_STORE_TRUST_PATH);
System.setProperty("javax.net.ssl.trustStorePassword", KEY_STORE_PASSWORD);
System.setProperty("javax.net.ssl.trustStoreType", "jks");
KeyStore kstore = KeyStore.getInstance("PKCS12");
kstore.load(new FileInputStream(KEY_STORE_CLIENT_PATH), KEY_STORE_PASSWORD.toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("sunx509");
keyFactory.init(kstore, KEY_STORE_PASSWORD.toCharArray());
KeyStore tstore = KeyStore.getInstance("jks");
tstore.load(new FileInputStream(KEY_STORE_TRUST_PATH), KEY_STORE_PASSWORD.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
tmf.init(tstore);
TrustManager[] tm = tmf.getTrustManagers();
sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyFactory.getKeyManagers(), tm, (SecureRandom) null);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String httpPost(String url, String jsonParam) {
try {
httpClient = new DefaultHttpClient();
SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
Scheme sch = new Scheme("https", 443, socketFactory);
httpClient.getConnectionManager().getSchemeRegistry().register(sch);
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json");
httpPost.addHeader("charset", "UTF-8");
httpPost.setEntity(new StringEntity(jsonParam.toString(), "UTF-8"));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity);
return result;
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}