如何设置JAX-WS web服务客户端的超时?
我已经使用JAXWS-RI 2.1为基于WSDL的Web服务创build一个接口。 我可以与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);
我的问题是,不pipe上面哪一个是正确的,我不知道我能在哪里做到这一点。 我所得到的只是一个Service
子类,它实现了自动生成的Web Service
接口,并且在WSDL不响应的情况下得到实例化,然后设置属性已经太迟了:
MyWebServiceSoap soap; MyWebService service = new MyWebService("http://www.google.com"); soap = service.getMyWebServiceSoap(); soap.sendRequestToMyWebService();
任何人都可以指向正确的方向吗?!
我知道这是旧的,并在其他地方回答,但希望这封闭了下来。 我不确定为什么要dynamic下载WSDL,但系统属性:
sun.net.client.defaultConnectTimeout (default: -1 (forever)) sun.net.client.defaultReadTimeout (default: -1 (forever))
应该适用于所有读取并使用JAX-WS使用的HttpURLConnection进行连接。 如果您从远程位置获取WSDL,这应该可以解决您的问题 – 但是本地磁盘上的文件可能更好!
接下来,如果你想为特定的服务设置超时,一旦你创build了你的代理,你需要把它转换成一个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);
当然,这是一个可怕的方式来做事情,我会创build一个很好的工厂来生产这些绑定提供程序,可以注入超时你想要的。
接受的答案中的属性对我来说不起作用,可能是因为我正在使用JAX-WS的JBoss实现?
使用一组不同的属性(可在JBoss JAX-WS用户指南中find )使其工作:
//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");
这是我的工作解决scheme:
// -------------------------- // 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."); } }
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);
这对我有效。
如果您在JDK6上使用JAX-WS,请使用以下属性:
com.sun.xml.internal.ws.connect.timeout com.sun.xml.internal.ws.request.timeout
不知道这是否会帮助你的情况下…
肥皂对象是否可以作为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调用时工作。
在实例化SEI时,避免缓慢检索远程WSDL的最简单方法是在运行时不从远程服务端点检索WSDL。
这意味着,只要服务提供商发生影响,就必须更新本地WSDL副本,但这也意味着,只要服务提供商发生影响,就必须更新本地副本。
当我生成我的客户端存根时,我告诉JAX-WS运行时以这样一种方式注释SEI,即它将从类path上的预定位置读取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哪里可以findWSDL,并且副本确保wsdl(和支持xsd ..等等)在正确的位置。
由于位置相对于SEI的包位置,我们创build一个名为wsdl的新子包(目录),并将所有wsdl构件复制到那里。
在这一点上你所要做的就是在创build客户端存根工件jar文件时,除了所有* .class外,还要确保包含所有的* .wsdl,* .xsd。
(万一你好奇的话@webserviceClient批注是这个wsdl位置实际上在java代码中设置的位置
@WebServiceClient(name = "httpServices", targetNamespace = "http://www.helter.com/schema/helter/httpServices", wsdlLocation = "./wsdl/helterHttpServices.wsdl")