问题描述
为了与项目的其他部分保持一致,我需要使用 RestTempate,我使用 BufferingClientHttpRequestFactory 因为响应被拦截并注销主体。
我有什么
在 springbootApplication 类中
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
RestTemplate template = builder
.setReadTimeout((int) Duration.ofSeconds(10).toMillis())
.setConnectTimeout((int)Duration.ofSeconds(10).toMillis())
.build();
template.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
List<ClientHttpRequestInterceptor> interceptorList = new ArrayList<ClientHttpRequestInterceptor>();
interceptorList.add(new LoggingInterceptor());
template.setInterceptors(interceptorList);
return template;}
在服务中
private ResponseEntity exchangeWithEndpointInternal(RequestEntity<?> request) throws IOException {
Instant requestStart = this.getClock().instant();
ResponseEntity response;
response = restTemplate.exchange(request,String.class);
Instant requestEnd = this.getClock().instant();
return response;
}
我的尝试:
覆盖bean定义中的verify方法
template.setRequestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory() {
@Override
protected void prepareConnection(HttpURLConnection connection,String httpMethod) throws IOException {
if (connection instanceof HttpsURLConnection) {
((HttpsURLConnection) connection).setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname,SSLSession session) {
return true;
}
});
}
super.prepareConnection(connection,httpMethod);
}
}));
使用 NoopHostVerifier
template.setRequestFactory(new BufferingClientHttpRequestFactory( new SimpleClientHttpRequestFactory() {
@Override
protected void prepareConnection(HttpURLConnection connection,String httpMethod) throws IOException {
if (connection instanceof HttpsURLConnection) {
((HttpsURLConnection) connection).setHostnameVerifier(new NoopHostnameVerifier());
}
super.prepareConnection(connection,httpMethod);
}
}));
都没有给我我正在寻找的输出,我需要忽略 SSL Validaiton,但我遇到了这个错误:
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://someHost/somePath": 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: PKIX path building Failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:742)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:635)
at com.....exchangeWithEndpointInternal(FreightapiclientViaHttp.java:97)
at com.....exchangeWithEndpoint(FreightapiclientViaHttp.java:77)
... 73 common frames omitted
有什么想法吗?我很高兴更改工厂,如果我仍然可以多次读取响应正文,这是以前使用 okHttpClient 工作的,没有 RestTemplate,如下所示:
final TrustManager[] trustAllCerts = new TrustManager[] {
new x509trustmanager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain,String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain,String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedissuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null,trustAllCerts,new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder.sslSocketFactory(sslSocketFactory,(x509trustmanager)trustAllCerts[0]);
okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname,SSLSession session) {
boolean whitelistedDomain = configuration.getSslDomainWhitelist().stream()
.peek(String::trim)
.filter(domain -> domain.equalsIgnoreCase(hostname))
.findAny()
.isPresent();
if (!whitelistedDomain) {
return OkHostnameVerifier.INSTANCE.verify(hostname,session);
} else {
return true;
}
}
});
但我无法用其他技术复制行为。
最后一点: 当我使用 curl 触发请求时,出现 SSL 错误,当我添加 -k 标志时,它就很好了。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)