I am using JAX-WS 4.x. When I make the SOAP calls from my client, I notice that the client side terminates the TCP connection after a set timeout. I can see the following headers in my SOAP HTTP request:
The user agent is XML-WS Runtime 4.0.0
.
In the image above, note that 100.64.0.1
is the client and it is initiating FIN.
In a separate test project I am using spring-ws-core for the client side code. My client extends the WebServiceGatewaySupport
class and I create the bean as below:
@Bean
public CountryClient countryClient(Jaxb2Marshaller marshaller, HttpComponentsMessageSender messageSender) {
CountryClient client = new CountryClient();
client.setDefaultUri("http://localhost:8043/ws");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
client.getWebServiceTemplate().setMessageSender(messageSender);
return client;
}
@Bean
public HttpComponentsMessageSender httpComponentsMessageSender() {
HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
messageSender.setConnectionTimeout(5 * 60 * 1000); // 5 minutes
messageSender.setReadTimeout(5 * 60 * 1000); // 5 minutes
return messageSender;
}
Now with this spring-ws based client when I make a SOAP call I see the following
The User Agent is changed to Apache-HttpClient and the TCP connection is not closed by the client side.
I wanted to see if I can use the same http client in JAX-WS so I tried the following suggestion that I came across but they don’t appear to work:
// None of the following timeout have any effect on keep-alive
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", 5*60*1000);
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 5*60*1000);
bindingProvider.getRequestContext().put("javax.xml.ws.client.connectionTimeout", 5*60*1000);
bindingProvider.getRequestContext().put("javax.xml.ws.client.receiveTimeout", 5*60*1000);
// Add HTTP client transport settings
CloseableHttpClient httpClient = createHttpClient();
// Use Apache HttpClient for requests
HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
messageSender.setConnectionTimeout(5 * 60 * 1000); // 5 minutes
messageSender.setReadTimeout(5 * 60 * 1000); // 5 minutes
messageSender.setHttpClient(httpClient);
// Assign the message sender to the BindingProvider
bindingProvider.getRequestContext().put("com.sun.xml.ws.transport.http.client.HttpTransportPipe.messageSender", messageSender);
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.messageSender", messageSender);
My main issue is that when the User Agent is XML-WS Runtime 4.0.0
the client has no effect of Keep-Alive flag and keep alive timeout. It automatically initiates a FIN after a timeout value that appears to be the default of the server side but is never communicated to client. I know this because I don’t see any timeouts or keep-alive set in the headers sent in the response sent by the server.
However, when the User Agent is Apache-HttpClient
, the keep-alive flag and the timeout set from the client, is honored and the TCP connection remains open instead of being closed by the client.
On the server side, I know I can set the server’s keep-alive timeout and that appears to work but in real scenario I don’t have control over the server. Instead I want JAX-WS to behave similar to Apache-HttpClient.
Question How can I change the User Agent of JAX-WS to be Apache-HttpClient
or how can I make JAX-WS to not close the TCP connection from the client? I only want solution that work on the client side and not on the server side.