Reputation: 55
I'm trying to integrate with an external webservice and it use a certificate with TLS 1.0 protocol.
I've tried setting -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2,SSLv3
but the outbound gateway still uses TLSv1.2
. It works correctly if I just limit the option to TLSv1
but I can't do that since I'm integrating to a lot of external services.
How can you set the protocol on the outbound gateway itself?
I tried doing that with this code but I ran to an exception:
SimpleWebServiceOutboundGateway handler = new SimpleWebServiceOutboundGateway(url);
HttpComponentsMessageSender sender = new HttpComponentsMessageSender();
SSLContext sslContext = SSLContext.getDefault();
sslContext.getDefaultSSLParameters().setProtocols(new String[]{"TLSv1"});
CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();
sender.setHttpClient(httpClient);
handler.setMessageSender(sender);
Exception:
Caused by: org.apache.http.client.ClientProtocolException: null
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
at org.springframework.ws.transport.http.HttpComponentsConnection.onSendAfterWrite(HttpComponentsConnection.java:121)
at org.springframework.ws.transport.AbstractWebServiceConnection.send(AbstractWebServiceConnection.java:48)
at org.springframework.ws.client.core.WebServiceTemplate.sendRequest(WebServiceTemplate.java:658)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:606)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
... 91 common frames omitted
Caused by: org.apache.http.ProtocolException: Content-Length header already present
at org.apache.http.protocol.RequestContent.process(RequestContent.java:97)
at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:133)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:182)
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)
... 99 common frames omitted
Upvotes: 1
Views: 1269
Reputation: 55
I looked at related documentations for HttpComponentsMessengerSender and found HttpComponentsMessageSender.RemoveSoapHeadersInterceptor
HttpClient HttpRequestInterceptor implementation that removes Content-Length and Transfer-Encoding headers from the request. Necessary, because some SAAJ and other SOAP implementations set these headers themselves, and HttpClient throws an exception if they have been set.
The solution is to add it to the interceptors of HttpComponentsMessengerSender
.
The final version of the sender is:
SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1").build();
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.addInterceptorFirst(new
HttpComponentsMessageSender.RemoveSoapHeadersInterceptor())
.build();
HttpComponentsMessageSender sender = new HttpComponentsMessageSender(httpClient);
Upvotes: 2