如何为 JAX-WS Web 服务客户机设置超时?

2022-08-31 10:06:03

我使用 JAXWS-RI 2.1 为我的 Web 服务创建了一个基于 WSDL 的接口。我可以毫无问题地与 Web 服务交互,但无法指定向 Web 服务发送请求的超时。如果由于某种原因它没有响应,客户似乎只是永远旋转它的轮子。

四处寻找已经发现,我可能应该尝试做这样的事情:

((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.ws.request.timeout", 10000);
((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.ws.connect.timeout", 10000);

我还发现,根据您拥有的 JAXWS-RI 版本,您可能需要设置以下属性:

((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 10000);
((BindingProvider)myInterface).getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", 10000);

我遇到的问题是,无论上述哪一个是正确的,我不知道我在哪里可以做到这一点。我所拥有的只是一个服务子类,它实现了自动生成的Web服务接口,并且在它被实例化的时候,如果WSDL没有响应,那么设置属性已经太晚了:

MyWebServiceSoap soap;
MyWebService service = new MyWebService("http://www.google.com");
soap = service.getMyWebServiceSoap();
soap.sendRequestToMyWebService();

任何人都可以给我指出正确的方向吗?!


答案 1

我知道这已经很老了,在其他地方回答了,但希望这能结束它。我不确定为什么你想动态下载WSDL,但系统属性:

sun.net.client.defaultConnectTimeout (default: -1 (forever))
sun.net.client.defaultReadTimeout (default: -1 (forever))

应应用于使用 JaX-WS 使用的 HttpURLConnection 的所有读取和连接。如果您从远程位置获取 WSDL,这应该可以解决您的问题 - 但是本地磁盘上的文件可能更好!

接下来,如果要为特定服务设置超时,一旦创建了代理,就需要将其强制转换为 BindingProvider(您已经知道),获取请求上下文并设置属性。在线 JAX-WS 文档是错误的,这些是正确的属性名称(好吧,它们对我有用)。

MyInterface myInterface = new MyInterfaceService().getMyInterfaceSOAP();
Map<String, Object> requestContext = ((BindingProvider)myInterface).getRequestContext();
requestContext.put(BindingProviderProperties.REQUEST_TIMEOUT, 3000); // Timeout in millis
requestContext.put(BindingProviderProperties.CONNECT_TIMEOUT, 1000); // Timeout in millis
myInterface.callMyRemoteMethodWith(myParameter);

当然,这是一种可怕的做事方式,我会创建一个很好的工厂来生产这些绑定提供程序,这些提供程序可以注入您想要的超时。


答案 2

接受的答案中的属性对我不起作用,可能是因为我使用的是 JAX-WS 的 JBoss 实现?

使用一组不同的属性(可在 JBoss JAX-WS 用户指南中找到)使它工作:

//Set timeout until a connection is established
((BindingProvider)port).getRequestContext().put("javax.xml.ws.client.connectionTimeout", "6000");

//Set timeout until the response is received
((BindingProvider) port).getRequestContext().put("javax.xml.ws.client.receiveTimeout", "1000");

推荐