簡體   English   中英

在 JAX-WS Web 服務中,如何在返回每個 Soap 調用后強制關閉套接字?

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

我正在使用 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 容器,應該模擬現有的 SOAP 服務,該服務是使用 Apache Axis 實現的,在 Tomcat 上運行。 現有客戶端同樣使用 Apache Axis 實現。

我遇到的問題是從客戶端到我的 JAX-WS 服務的 Soap 操作調用掛起一段時間,然后在客戶端以套接字超時結束。 即使 JAX-WS 服務立即返回 SOAP 響應,也會發生這種情況。

使用 tcpdump 和 wireshark 檢查數據包,我注意到使用現有的 Axis Web 服務,在 SOAP 響應從服務器發送到客戶端后,服務器發送一個“FIN ACK”數據包,客戶端響應“FIN ACK” ”。 與 SOAP 操作相關的所有數據包到此結束。 另一方面,當與 JAX-WS 服務一起運行時,在將 SOAP 響應發送到客戶端后,服務器不會發送“FIN ACK”。 並且客戶端似乎繼續為它讀取套接字輸入流。

這讓我相信 JAX-WS Web 服務堆棧以某種方式保持套接字打開,即使在發送了對 SOAP 調用的響應之后也是如此。 並且客戶端似乎希望套接字在 SOAP 操作結束時關閉。 不幸的是,我無法修改客戶端以使其行為有所不同。

有沒有辦法將我用來發布 JAX-WS 服務的端點或 HttpServer 實例配置為在每次 SOAP 操作后始終關閉套接字?

我嘗試將系統屬性 http.keepAlive 設置為 false,但這似乎沒有任何區別。

在此先感謝您的幫助。

我找到了解決此問題的方法,但是它不是很優雅。 本質上,在Endpoint.publish操作創建了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();
    }
  }

它可以滿足我當前的需求,但是似乎有一種更好的方法。 如果您還有其他解決方案,請發表。 謝謝!

當我在 Java 8 中遇到這個問題時,來自 JAX-WS RI 2.2.9 的所有請求都有標頭: Connection: keep-alive

為了在每次請求后強制關閉 TCP 連接,我必須將此標頭更改為Connection: close

我是通過以下方式做到的:

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);

在哪里:

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