- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 restTemplate 通过 SSL 请求发布。问题是我无法通过 SSL 向服务器发送发布请求。我正在使用自签名证书进行通信。然而,奇怪的是,当我通过 SSL 发送获取请求时,它工作正常。
我不明白为什么 POST 不像 GET 那样工作。这是我使用 restTemplate 的 GET 和 POST。
public <T> T getByRestTemplate(String url, Object param, boolean isSSL, String token, ParameterizedTypeReference<T> responseType) throws RestClientException {
HttpEntity<Object> requestEntity = makeHttpEntity(param, token);
RestTemplate restTemplate = buildRestTemplate(isSSL);
ResponseEntity<T> responseEntity;
responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, responseType);
return responseEntity.getBody();
}
public <T> T postByRestTemplate(String url, Object param, boolean isSSL, String token, Class<T> responseType) throws RestClientException {
HttpEntity<Object> requestEntity = makeHttpEntity(param, token);
RestTemplate restTemplate = prepareRestTemplate(isSSL);
ResponseEntity<T> responseEntity;
responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType);
return responseEntity.getBody();
}
private RestTemplate prepareRestTemplate(boolean isSSL){
int connectTimeOut = (appConfigProperties.getConnectTimeOut()!=0)?appConfigProperties.getConnectTimeOut():5000;
int readTimeOut = (appConfigProperties.getReadTimeOut()!=0)?appConfigProperties.getConnectTimeOut():5000;
RestTemplate restTemplate = buildRestTemplate(isSSL);
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(connectTimeOut);
requestFactory.setReadTimeout(readTimeOut);
restTemplate.setRequestFactory(requestFactory);
return restTemplate;
}
private RestTemplate buildRestTemplate(boolean isSSL) {
RestTemplate restTemplate = null;
if (isSSL) {
try {
restTemplate = restTemplateSSL.restTemplateSSL();
} catch (Exception e) {
e.printStackTrace();
}
} else {
restTemplate = restTemplateBuilder.build();
}
return restTemplate;
}
这里是与SSL设置相关的代码。
private static TrustManager[] createTrustManagers() {
TrustManager[] trustAllCerts;
trustAllCerts = new TrustManager[]{new X509ExtendedTrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s){
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s, Socket socket) {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s, Socket socket) {
}
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) {
}
}};
return trustAllCerts;
}
public RestTemplate restTemplateSSL() throws Exception {
SSLContext sslContext = SSLContext.getInstance(SSL_TLS);
sslContext.init(null, createTrustManagers(), new java.security.SecureRandom());
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext,
NoopHostnameVerifier.INSTANCE);
final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register(SSL_HTTPS, csf)
.build();
final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.setConnectionManager(cm)
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return new RestTemplate(requestFactory);
}
这是我得到的日志。
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] with root cause
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) ~[na:1.8.0_192]
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) ~[na:1.8.0_192]
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) ~[na:1.8.0_192]
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392) ~[na:1.8.0_192]
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302) ~[na:1.8.0_192]
at sun.security.validator.Validator.validate(Validator.java:262) ~[na:1.8.0_192]
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) ~[na:1.8.0_192]
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) ~[na:1.8.0_192]
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) ~[na:1.8.0_192]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621) ~[na:1.8.0_192]
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223) ~[na:1.8.0_192]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037) ~[na:1.8.0_192]
at sun.security.ssl.Handshaker.process_record(Handshaker.java:965) ~[na:1.8.0_192]
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064) ~[na:1.8.0_192]
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367) ~[na:1.8.0_192]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395) ~[na:1.8.0_192]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379) ~[na:1.8.0_192]
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:374) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.9.jar:4.5.9]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) ~[httpclient-4.5.9.jar:4.5.9]
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:579) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
我已经阅读了许多其他帖子和 stackoverflow 问答
Access Https Rest Service using Spring RestTemplate
How to disable SSL certificate checking with Spring RestTemplate?
Disabling SSL Certificate Validation in Spring RestTemplate
还有更多关于这个问题的内容。但没有成功。我不确定我还能尝试其他方法。
最佳答案
毕竟这是一个愚蠢的错误。
我在为 POST 请求设置 restClient 时犯了一个错误,覆盖了 RequestFactory,因此删除了之前的 SSL 连接设置。
希望没有人会犯这种错误!
关于Spring RestTemplate 交换帖子不适用于 SSL 抛出 SunCertPathBuilderException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59405847/
我是一名优秀的程序员,十分优秀!