在项目中遇到java请求HTTPS,会报异常
javax.net.ssl.SSLHandshakeException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
在网上查了一堆资料,(忘记是哪位大佬的博客了)。然后写了一个类
public class httpUtils{
public static void main(String[] args) {
Map<String, String> headers = new HashMap<>(16);
headers.put("Content-Type","application/x-www-form-urlencoded");
String name = "sw";
String url = "https://localhost:8080/v2/oauth/token";
String sw = "grant_type=client_with_su&scope=all&slug="+name;
JSONObject jsonObject = postFormUrlEncoded(url,sw,headers);
System.out.println(jsonObject);
String access_token = jsonObject.getString("access_token");
System.out.println(access_token);
}
public static JSONObject postFormUrlEncoded(String targetUrl, String params,Map<String, String> headers) {
HttpURLConnection urlConnection = null;
try {
URL url = new URL(targetUrl.trim());
trustAllHttpsCertificates();
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
urlConnection = (HttpURLConnection) url.openConnection();
// 设置请求方式
urlConnection.setRequestMethod("POST");
// 设置数据类型
urlConnection.setRequestProperty("accept", "*/*");
urlConnection.setRequestProperty("connection", "Keep-Alive");
urlConnection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
if (headers != null) {
Set<String> keySet = headers.keySet();
for (String key : keySet) {
urlConnection.setRequestProperty(key, headers.get(key));
}
}
// 设置允许输入输出
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
// 设置不用缓存
urlConnection.setUseCaches(false);
urlConnection.connect();
PrintWriter out = new PrintWriter(new OutputStreamWriter(urlConnection.getOutputStream(), StandardCharsets.UTF_8));
// 写入传递参数,格式为a=b&c=d
out.print(params);
out.flush();
int resultCode = urlConnection.getResponseCode();
if (HttpURLConnection.HTTP_OK == resultCode) {
StringBuffer stringBuffer = new StringBuffer();
String readLine;
BufferedReader responseReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8));
while ((readLine = responseReader.readLine()) != null) {
stringBuffer.append(readLine);
}
responseReader.close();
return JSONObject.parseObject(stringBuffer.toString());
}
out.close();
} catch (Exception e) {
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
}
static class miTM implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
调用https之前先调用
trustAllHttpsCertificates();
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);