java - 在 JAX-WS Web 服务中,如何在返回每个 Soap 调用后强制关闭套接字?

标签 java soap network-programming jax-ws java-6

我正在使用 com.sun.httpserver.HttpServer 和 javax.xml.ws.Endpoint 发布 JAX-WS Web 服务,该服务是通过在现有 WSDL 上运行 wsimport 并实现生成的服务接口(interface)生成的。所有这些都是 JDK 1.6 (JAX-WS RI 2.1.6) 的一部分。我的 Web 服务作为一个 Java 程序运行,没有额外的 Web 容器,应该模拟一个现有的 SOAP 服务,该服务是使用 Apache Axis 实现的,在 Tomcat 上运行。现有客户端同样使用 Apache Axis 实现。

我遇到的问题是,从客户端到我的 JAX-WS 服务的 Soap 操作调用会挂起一段时间,然后在客户端以套接字超时结束。即使 JAX-WS 服务立即返回 SOAP 响应,也会发生这种情况。

使用 tcpdump 和 wireshark 检查数据包,我注意到在现有的 Axis web 服务中,在 SOAP 响应从服务器发送到客户端后,服务器发送一个“FIN ACK”数据包,客户端响应“鳍确认”。这结束了与 SOAP 操作相关的所有数据包。另一方面,当使用 JAX-WS 服务运行时,服务器不会在将 SOAP 响应发送到客户端后发送“FIN ACK”。并且客户端似乎继续为它读取套接字输入流。

这使我相信 JAX-WS Web 服务堆栈以某种方式保持套接字打开,即使在发送对 SOAP 调用的响应之后也是如此。客户端似乎希望套接字在 SOAP 操作结束时关闭。不幸的是,我无法修改客户端以使其行为不同。

有没有办法将我用来发布 JAX-WS 服务的端点或 HttpServer 实例配置为在每次 SOAP 操作后始终关闭套接字?

我尝试将系统属性 http.keepAlive 设置为 false,但这似乎没有任何区别。

预先感谢您的帮助。

最佳答案

我找到了解决这个问题的方法,但不是很优雅。本质上,在 Endpoint.publish 操作创建 HttpHandler 对象后,我从 HttpContext 获取它。然后我从我编写的另一个 HttpHandler 类调用它的 handle() 方法,该方法通过发送一个将“Connection”设置为“close”的 HttpHeader 来跟进它。像这样:

  ...
  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();
    }
  }

它可以满足我当前的需求,但似乎必须有更好的方法。如果您有其他解决方案,请发帖。谢谢!

关于java - 在 JAX-WS Web 服务中,如何在返回每个 Soap 调用后强制关闭套接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7449167/

相关文章:

java - 如何修复 'Codility FrogJump' 算法?

java - 如何在 Play Framework 2.3.8 中保留字符串集合?

java - 为什么我不能将键盘字符串输入放在其他键盘输入之后?

java - 如何在 Android 中进行搜索

java - 如何创建用于 Web 服务的密码摘要?

javascript - 如何让apache服务器发送特定的 header

php - 使用 PHP 和 NuSOAP 通过 HTTPS 发出 SOAP 请求

android - InetAddress.getLocalHost() 总是崩溃

c++ - 在 C/C++ 中实现跨平台、多线程服务器的最佳方法是什么?

java - 为什么我的应用程序在尝试建立 http 连接时不断崩溃?