In the JAX-WS web service, how can I get the socket to close after each soap call?

I am using com.sun.httpserver.HttpServer and javax.xml.ws.Endpoint to publish the JAX-WS web service that was generated when wsimport was launched in the existing WSDL and implemented the functional interface. All this was part of JDK 1.6 (JAX-WS RI 2.1.6). My web service, running as a Java program without an additional web container, should mimic an existing SOAP service that was implemented using Apache Axis running on Tomcat. Existing clients are also implemented using Apache Axis.

The problem I encountered is that the Soap operation causes my JAX-WS service from the clients for a while, and then completes the socket timeout on the client side. This happens even if the JAX-WS service immediately returns a SOAP response.

Checking the packets with tcpdump and wirehark, I noticed that with the existing Axis web service, after sending the SOAP response from the server to the client, the server sends a “FIN ACK” packet to which clients respond with “FIN ACK”. This completes all packets related to the SOAP operation. On the other hand, when working with the JAX-WS service, the server does not send a “FIN ACK” after sending a SOAP response to the client. And the client seems to continue reading the socket input stream for it.

This makes me think that the JAX-WS web services stack somehow closes the socket, even after the response to the SOAP call has been sent. And it looks like the client is expecting the socket to close at the end of the SOAP operation. Unfortunately, I cannot change the client to behave differently.

Is there a way to configure the Endpoint or HttpServer instances that I use to publish the JAX-WS service to always close the socket after every SOAP operation?

I tried setting the system property http.keepAlive to false, but that didn't seem to make any difference.

Thanks in advance for your help.

+4
source share
1 answer

I found a way around this problem, but it is not very elegant. Essentially, I get the HttpHandler object from the HttpContext after creating it using the Endpoint.publish operation. And I call my handle () method from another HttpHandler class that I wrote that follows it, sending the HttpHeader with "Connection" set to "close". Something like that:

... HttpServer server = HttpServer.create(myInetSocketAddress, 5); HttpContext context = server.createContext(mySoapPath); Endpoint endpoint = Endpoint.create(mySoapImpl); endpoint.publish(context); MyHandler handler = new MyHandler(context.getHandler()); server.removeContext(mySoapPath); server.createContext(mySoapPath, handler); server.start(); ... private class MyHandler implements HttpHandler { private HttpHandler h; public MyHandler(HttpHandler in) { h = in; } public void handle(HttpExchange t) throws IOException { h.handle(t); t.getResponseHeaders().set("Connection", "close"); t.sendResponseHeaders(200, 0); t.close(); } } 

It works for my current needs, but it seems like this is the best way. Please send a message if you have another solution. Thanks!

+2
source

All Articles