我必须在没有任何参数的情况下向某些 API 发送 GET 请求,所以我编写了代码:
public Boolean getData(String apiUrl) {
try {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate.getForEntity(apiUrl, String.class);
if (responseEntity.getStatusCode().toString().equals("200")) {
theLogger.info("Server successfully answered with response code: {} - {}", responseEntity.getStatusCode().toString(), responseEntity.getBody());
return true;
} else {
theLogger.error("Something goes wrong! Server answered with response code: {} and error: {}", responseEntity.getStatusCode().toString(), responseEntity.getBody());
return false;
}
} catch (Exception theException) {
theException.printStackTrace();
theLogger.error("Cannot send channelInfo! Exception: " + theException);
return false;
}
}
它在 API url 为 HTTP 时有效,但不适用于 HTTPS。它说:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is 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
我相信这是因为我的代码不信任这个证书。但我不知道该怎么办? API 是公开的,它可以在任何网络浏览器中打开,它只是一些 https 站点。我简直不敢相信我应该为我使用的所有 https 站点下载证书并将这些证书添加到某个地方。我相信这应该是更普遍的方式来信任这个公共(public)网站。
最佳答案
我找到了答案 here 因此,如果必须处理由不受信任的 CA 颁发的证书,但在您的情况下,您并不真正关心信任。您可以通过代码禁用 SSL 证书验证:
import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class SSLCertificateValidation {
public static void disable() {
try {
SSLContext sslc = SSLContext.getInstance("TLS");
TrustManager[] trustManagerArray = { new NullX509TrustManager() };
sslc.init(null, trustManagerArray, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new NullHostnameVerifier());
} catch(Exception e) {
e.printStackTrace();
}
}
private static class NullX509TrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
System.out.println();
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
System.out.println();
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
private static class NullHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
}
在进行 HTTPS 调用之前调用 SSLCertificateValidation.disable()。
关于Java Spring : How to send http request to https urls?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34906467/