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


93

我已经使用JAXWS-RI 2.1为基于WSDL的Web服务创建了一个接口。我可以与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);

我的问题是,无论以上哪一项是正确的,我都不知道该在哪里做。我所拥有的只是一个Service子类,该子类实现了自动生成的Web服务接口,并且当实例化时,如果WSDL没有响应,那么设置属性已经为时已晚:

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

谁能指出我正确的方向?


5
我想我没有答案,但是您的问题帮助我解决了问题。我知道com.sun.xml.ws.request.timeout属性,但不了解com.sun.xml.internal.ws.request.timeout属性。
罗恩·塔芬

Answers:


89

我知道这很古老,可以在其他地方回答,但希望这可以解决这个问题。我不确定为什么要动态下载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);

当然,这是一种可怕的处理方式,我将创建一个不错的工厂来生成这些绑定提供程序,并可以将其与所需的超时一起注入。


10
请注意,REQUEST_TIMEOUT / CONNECT_TIMEOUT属性实际上是从SUN内部类com.sun.xml.internal.ws.developer.JAXWSProperties和(至少在32位Linux上)javac 1.6.0_27和javac 1.7.0_03继承的编译此代码(类似于bugs.sun.com/view_bug.do?bug_id=6544224)...您需要将-XDignore.symbol.file传递给javac才能使其正常工作。
JavaGuy 2012年

什么不起作用?我只是仔细检查了一下,它对我有用。
阿尔卑斯山2012年

只要确认我刚刚在JAX-WS RI 2.2.8和JDK 1.7中使用了它,它就可以正常工作。谢谢!
bconneen 2014年

完全合格名称中具有“内部”名称的类和参数不应使用,因为它们与供应商有关,因此不能在不同的JDK实现中移植。例如,对于jax-ws参数,com.sun.xml.ws.client.BindingProviderProperties类中存在相应的非内部属性。
Polaretto 2015年

1
@ Matt1776是的,它当然会丢失:尽管JAX-WS是API规范,但是您需要一个库实现,在这种情况下是jaxws-ri.jar或jaxws-rt.jar,它不是JDK的一部分。您只需要下载并将其添加到您的ptoject中,就可以使用这些属性。
Polaretto '16

38

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

使用一组不同的属性(可在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");

2
我没有在使用JBoss,但是只有此注释中的属性对我有用,其他什么也没有。
PaulP 2015年

2
属性名称取决于JAX-WS实现。可以在此处找到列表:java.net/jira/browse/JAX_WS-1166
fabstab '16


12

这是我的工作解决方案:

// --------------------------
// SOAP Message creation
// --------------------------
SOAPMessage sm = MessageFactory.newInstance().createMessage();
sm.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
sm.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-8");

SOAPPart sp = sm.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
se.setEncodingStyle("http://schemas.xmlsoap.org/soap/encoding/");
se.setAttribute("xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/");
se.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
se.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

SOAPBody sb = sm.getSOAPBody();
// 
// Add all input fields here ...
// 

SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
// -----------------------------------
// URL creation with TimeOut connexion
// -----------------------------------
URL endpoint = new URL(null,
                      "http://myDomain/myWebService.php",
                    new URLStreamHandler() { // Anonymous (inline) class
                    @Override
                    protected URLConnection openConnection(URL url) throws IOException {
                    URL clone_url = new URL(url.toString());
                    HttpURLConnection clone_urlconnection = (HttpURLConnection) clone_url.openConnection();
                    // TimeOut settings
                    clone_urlconnection.setConnectTimeout(10000);
                    clone_urlconnection.setReadTimeout(10000);
                    return(clone_urlconnection);
                    }
                });


try {
    // -----------------
    // Send SOAP message
    // -----------------
    SOAPMessage retour = connection.call(sm, endpoint);
}
catch(Exception e) {
    if ((e instanceof com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl) && (e.getCause()!=null) && (e.getCause().getCause()!=null) && (e.getCause().getCause().getCause()!=null)) {
        System.err.println("[" + e + "] Error sending SOAP message. Initial error cause = " + e.getCause().getCause().getCause());
    }
    else {
        System.err.println("[" + e + "] Error sending SOAP message.");

    }
}

3
这些配置是否等效于“ javax.xml.ws.client.connectionTimeout”和“ javax.xml.ws.client.receiveTimeout”?
Jose Tepedino

11
ProxyWs proxy = (ProxyWs) factory.create();
Client client = ClientProxy.getClient(proxy);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(0);
httpClientPolicy.setReceiveTimeout(0);
http.setClient(httpClientPolicy);

这对我有用。


谢谢!对我来说,这也是一个非常简单的方法
kosm 2014年

4
尽管它使用Apache CXF类,但最好将其添加到答案中。CXF罐子包含它们的链接也会有很大帮助。
JBert 2014年

@JBert我同意。我几年前回答了,不记得了。随时编辑答案。
Daniel Kaplan 2014年

8

如果要在JDK6上使用JAX-WS,请使用以下属性:

com.sun.xml.internal.ws.connect.timeout  
com.sun.xml.internal.ws.request.timeout

System.setProperty(“ com.sun.xml.internal.ws.connect.timeout”,“ 300”); System.setProperty(“ com.sun.xml.internal.ws.request.timeout”,“ 300”)为我工作。
2787184

2
在某些情况下,您不知道将在运行时使用哪个JAXWS版本(内部或独立)的编程时间。除了超时功能外,两者非常兼容。键是不同的(com.sun.xml.internal.ws.connect.timeoutvs com.sun.xml.ws.connect.timeout)还是定义它们的类(/接口)(com.sun.xml.internal.ws.developer.JAXWSProperties/ com.sun.xml.internal.ws.client.BindingProviderPropertiesvs com.sun.xml.ws.developer.JAXWSProperties/ com.sun.xml.ws.client.BindingProviderProperties)。我最好的主意是同时使用文字值作为键来设置两者。
洛林奇·齐格蒙德'18

5

如果您的应用服务器是WebLogic(对我来说是10.3.6),那么负责超时的属性是:

com.sun.xml.ws.connect.timeout 
com.sun.xml.ws.request.timeout

3

不确定这是否对您有帮助...

可以将soap对象强制转换为BindingProvider吗?

MyWebServiceSoap soap;
MyWebService service = new MyWebService("http://www.google.com");
soap = service.getMyWebServiceSoap();
// set timeouts here
((BindingProvider)soap).getRequestContext().put("com.sun.xml.internal.ws.request.timeout", 10000);
    soap.sendRequestToMyWebService();

另一方面,如果要在MyWebService对象的初始化上设置超时,则将无济于事。

当想使单个WebService调用超时时,这对我有用。


2

实例化SEI时,避免缓慢检索远程WSDL的最简单方法是在运行时不从远程服务端点检索WSDL。

这意味着您必须在服务提供商进行有影响力的更改时更新本地WSDL副本,但这也意味着您必须在服务提供商进行有影响力的更改时更新本地WSDL副本。

当我生成客户端存根时,我告诉JAX-WS运行时以这样一种方式注释SEI,即它将从类路径上的预定位置读取WSDL。默认情况下,该位置相对于服务SEI的程序包位置


<wsimport
    sourcedestdir="${dao.helter.dir}/build/generated"
    destdir="${dao.helter.dir}/build/bin/generated"
    wsdl="${dao.helter.dir}/src/resources/schema/helter/helterHttpServices.wsdl"
    wsdlLocation="./wsdl/helterHttpServices.wsdl"
    package="com.helter.esp.dao.helter.jaxws"
    >
    <binding dir="${dao.helter.dir}/src/resources/schema/helter" includes="*.xsd"/>
</wsimport>
<copy todir="${dao.helter.dir}/build/bin/generated/com/helter/esp/dao/helter/jaxws/wsdl">
    <fileset dir="${dao.helter.dir}/src/resources/schema/helter" includes="*" />
</copy>

wsldLocation属性告诉SEI在哪里可以找到WSDL,并且副本确保wsdl(以及支持xsd ..等)在正确的位置。

由于该位置是相对于SEI的程序包位置而言的,因此我们创建了一个名为wsdl的新子程序包(目录),并在其中复制所有wsdl工件。

此时,您要做的就是确保在创建客户端存根工件JAR文件时,除了所有* .class之外,还包括所有* .wsdl,*。xsd。

(以防您好奇,@ webserviceClient注释是在Java代码中实际设置此wsdl位置的位置

@WebServiceClient(name = "httpServices", targetNamespace = "http://www.helter.com/schema/helter/httpServices", wsdlLocation = "./wsdl/helterHttpServices.wsdl")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.