简体   繁体   English

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

[英]In a JAX-WS web service, how do I force a socket close after each Soap call is returned?

I am using com.sun.httpserver.HttpServer and javax.xml.ws.Endpoint to publish a JAX-WS web service, which was generated by running wsimport on an existing WSDL and implementing the genereated service interface.我正在使用 com.sun.httpserver.HttpServer 和 javax.xml.ws.Endpoint 发布 JAX-WS Web 服务,该服务是通过在现有 WSDL 上运行 wsimport 并实现生成的服务接口生成的。 All this was part of JDK 1.6 (JAX-WS RI 2.1.6).所有这些都是 JDK 1.6 (JAX-WS RI 2.1.6) 的一部分。 My web service, running as a Java program without an additional Web container is supposed to simulate an existing SOAP service that was implemented using Apache Axis, running on Tomcat.我的 Web 服务作为 Java 程序运行,没有额外的 Web 容器,应该模拟现有的 SOAP 服务,该服务是使用 Apache Axis 实现的,在 Tomcat 上运行。 Existing clients are likewise implemented using Apache Axis.现有客户端同样使用 Apache Axis 实现。

The problem I am having is that Soap operation calls from the clients to my JAX-WS service hang for a while, and then end with socket time-out on the client's side.我遇到的问题是从客户端到我的 JAX-WS 服务的 Soap 操作调用挂起一段时间,然后在客户端以套接字超时结束。 This occurs even though the JAX-WS service is returning the SOAP response right away.即使 JAX-WS 服务立即返回 SOAP 响应,也会发生这种情况。

Inspecting the packets with tcpdump and wireshark, I noticed that with the existing Axis web service, after the SOAP response is sent from the server to the client, the server sends a "FIN ACK" packet, to which the clients responds with "FIN ACK".使用 tcpdump 和 wireshark 检查数据包,我注意到使用现有的 Axis Web 服务,在 SOAP 响应从服务器发送到客户端后,服务器发送一个“FIN ACK”数据包,客户端响应“FIN ACK” ”。 This concludes all packets pertinent to the SOAP operation.与 SOAP 操作相关的所有数据包到此结束。 On the other hand, when running with the JAX-WS service, the server does not send a "FIN ACK" after the SOAP response is sent to the client.另一方面,当与 JAX-WS 服务一起运行时,在将 SOAP 响应发送到客户端后,服务器不会发送“FIN ACK”。 And the client seems to continue reading the socket input stream for it.并且客户端似乎继续为它读取套接字输入流。

This leads me to believe that the JAX-WS web service stack is somehow keeping the socket open, even after the response to a SOAP call has been sent.这让我相信 JAX-WS Web 服务堆栈以某种方式保持套接字打开,即使在发送了对 SOAP 调用的响应之后也是如此。 And it appears that the client is expecting the socket to close at the end of a SOAP operation.并且客户端似乎希望套接字在 SOAP 操作结束时关闭。 Unfortunately, I cannot modify the client to behave differently.不幸的是,我无法修改客户端以使其行为有所不同。

Is there a way to configure the Endpoint or the HttpServer instances that I am using to publish the JAX-WS service to always close a socket after each SOAP operation?有没有办法将我用来发布 JAX-WS 服务的端点或 HttpServer 实例配置为在每次 SOAP 操作后始终关闭套接字?

I tried setting the system property http.keepAlive to false, but this did not seem to make any difference.我尝试将系统属性 http.keepAlive 设置为 false,但这似乎没有任何区别。

Thanks in advance for your help.在此先感谢您的帮助。

I found a way around this problem, but it's not very elegant. 我找到了解决此问题的方法,但是它不是很优雅。 Essentially I get the HttpHandler object from the HttpContext after it's been created by the Endpoint.publish operation. 本质上,在Endpoint.publish操作创建了HttpContext对象之后,我从HttpHandler对象获得了它。 And I call its handle() method from another HttpHandler class I wrote, which follows it up by sending a HttpHeader with "Connection" set to "close". 然后从我编写的另一个HttpHandler类中调用其handle()方法,该类通过发送HttpHeader并将其“ Connection”设置为“ close”来跟进。 Something like this: 像这样:

  ...
  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 just seems like there's got to be a better way. 它可以满足我当前的需求,但是似乎有一种更好的方法。 Please do post if you have another solution. 如果您还有其他解决方案,请发表。 Thanks! 谢谢!

When I had this problem in Java 8 all requests from JAX-WS RI 2.2.9 had header: Connection: keep-alive当我在 Java 8 中遇到这个问题时,来自 JAX-WS RI 2.2.9 的所有请求都有标头: Connection: keep-alive

To force closing TCP connection after each request I had to change this header to Connection: close为了在每次请求后强制关闭 TCP 连接,我必须将此标头更改为Connection: close

I had done it by:我是通过以下方式做到的:

SoapService service = new SoapService(url);
SoapPort port = service.getSomePort();

Map<String, List<String>> requestHeaders = new HashMap<>();
requestHeaders.put("Connection", Collections.singletonList("close"));
BindingProvider bindingProvider = (BindingProvider)port;
bindingProvider.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders);

where:在哪里:

public static final String HTTP_REQUEST_HEADERS = "javax.xml.ws.http.request.headers";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM