使用javax.xml.soap.SOAPConnection设置套接字读取超时时间

18

我正在使用javax.xml.soap API(javax.xml.soap.SOAPConnectionFactory, javax.xml.soap.SOAPConnection等)呼叫远程服务器的Web服务,大部分时间都很成功。

但是,有时候会出现问题,程序陷入无限阅读的困境。

为了解决这个问题,我想添加一个读取超时。

我找到了几种可能实现这个目标的方法,但它们似乎都不太好用。

所以我的问题是:在使用javax.xml.soap API进行调用时,实现读取超时行为的最佳方法是什么?


嗨,塞缪尔请看下面的问题,因为它与您的问题有些相似。 希望您能在这里提出一些建议 https://stackoverflow.com/questions/47861767/http-connect-timeout-and-read-timeout-for-urlstreamhandler-with-saaj-working-fo - Parul Chauhan
3个回答

41

你需要创建自己的URLStreamHandler,这样你才能设置URLConnection参数,如连接超时和读取超时。

SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
URL endpoint =
  new URL(new URL("http://yourserver.yourdomain.com/"),
          "/path/to/webservice",
          new URLStreamHandler() {
            @Override
            protected URLConnection openConnection(URL url) throws IOException {
              URL target = new URL(url.toString());
              URLConnection connection = target.openConnection();
              // Connection settings
              connection.setConnectTimeout(10000); // 10 sec
              connection.setReadTimeout(60000); // 1 min
              return(connection);
            }
          });

SOAPMessage result = connection.call(soapMessage, endpoint);

为了清晰起见,我删除了一些try/catch。


你是否将传递给 openConnection 的 URL 转换为字符串,然后再转换回来,以防止 target.openConnection 使用定义的 URLStreamHandler? - Samuel Edwin Ward
那是一个很好的观点。我自己没有测试过,但我认为你猜对了:无限递归是关闭的 ;) 老实说,我从这里得到了那段代码:https://dev59.com/z3I95IYBdhLWcg3wzRPv - Yves Martin
很有趣,我想我看到了那个问题,但没有看答案,因为它是一个不同的问题(我认为那个答案并没有真正解决这个问题)。 - Samuel Edwin Ward
1
你说得对。经常会混淆传统的 SOAP API(你的问题)和基于 JAX-WS 注解的新 API(Zaki 在这里的回答)。 - Yves Martin
@YvesMartin 请抽出一些时间回答下面的问题。我正在尝试设置连接和读取超时,这在我的Windows操作系统上运行良好,但在基于Linux的系统上无法按预期工作。https://stackoverflow.com/questions/47861767/http-connect-timeout-and-read-timeout-for-urlstreamhandler-with-saaj-working-fo - Parul Chauhan
2
我非常确定这个不再起作用了。在调用方法中,HttpSOAPConnection(版本1.5.2)覆盖了两个超时。 - T3rm1

4
import com.sun.xml.internal.ws.client.BindingProviderProperties

public someResponse callWebService() {

    MyPort port = new Service().getPort();

    Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();

    requestContext.put(BindingProviderProperties.CONNECT_TIMEOUT, 10 * 1000); //10 secs

    requestContext.put(BindingProviderProperties.REQUEST_TIMEOUT, 1 * 60 * 1000); //1 min

    return port.someWebMethod();

}

什么是“服务”?我认为你可能回答了一个与我所问的不同的问题。 - Samuel Edwin Ward
这段代码片段对应于使用JAX-WS注解通过WSDL获取一个WebService的服务端口。 - Yves Martin

3
对于 saaj 实现(版本 1.5.2),可以设置 Java 系统属性。
saaj.connect.timeout

并且

saaj.read.timeout

Value是以毫秒为单位的超时时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接