我使用com.sun.httpserver.HttpServer和
javax.xml.ws.Endpoint来发布JAX-WS Web服务,该服务是通过在现有WSDL上运行wsimport并实现生成的服务接口生成的.所有这些都是JDK 1.6(JAX-WS RI 2.1.6)的一部分.我的Web服务作为
Java程序运行,没有额外的Web容器,应该模拟使用在Tomcat上运行的Apache Axis实现的现有SOAP服务.现有客户端同样使用Apache Axis实现.
我遇到的问题是从客户端到我的JAX-WS服务的Soap操作调用挂了一段时间,然后在客户端以套接字超时结束.即使JAX-WS服务立即返回SOAP响应,也会发生这种情况.
使用tcpdump和wireshark检查数据包,我注意到使用现有的Axis Web服务,在从服务器向客户端发送SOAP响应之后,服务器发送一个“FIN ACK”数据包,客户端以“FIN ACK”响应”.这结束了与SOAP操作相关的所有数据包.另一方面,当使用JAX-WS服务运行时,在将SOAP响应发送到客户端之后,服务器不会发送“FIN ACK”.客户端似乎继续为它读取套接字输入流.
这使我相信即使在发送了对SOAP调用的响应之后,JAX-WS Web服务堆栈仍以某种方式保持套接字打开.并且看起来客户端期望套接字在SOAP操作结束时关闭.不幸的是,我无法修改客户端以表现不同.
有没有办法配置我用来发布JAX-WS服务的Endpoint或HttpServer实例,以便在每次SOAP操作后始终关闭套接字?
我尝试将系统属性http.keepAlive设置为false,但这似乎没有任何区别.
在此先感谢您的帮助.
最佳答案 我找到了解决这个问题的方法,但它不是很优雅.实际上,在通过Endpoint.publish操作创建HttpContext之后,我从HttpContext获取了HttpHandler对象.我从我写的另一个HttpHandler类中调用了它的handle()方法,它通过发送一个HttpHeader并将“Connection”设置为“close”来跟进它.像这样的东西:
...
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();
}
}
它适用于我目前的需求,但似乎必须有一个更好的方法.如果您有其他解决方案,请发布.谢谢!