我已经使用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
子类,它实现了自动生成的webservice接口,并且实现了这种接口,如果WSDL没有响应,那么设置属性已经太晚了:
MyWebServiceSoap soap;
MyWebService service = new MyWebService("http://www.google.com");
soap = service.getMyWebServiceSoap();
soap.sendRequestToMyWebService();
有人能指出我正确的方向吗?!
答案 0 :(得分:82)
我知道这已经过时了,并在其他地方得到了解答,但希望这会让这个结束。我不确定你为什么要动态下载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);
当然,这是一种可怕的做事方式,我会创建一个很好的工厂来生产这些绑定提供程序,可以注入你想要的超时。
答案 1 :(得分:32)
接受的答案中的属性对我不起作用,可能是因为我正在使用JAX-WS的JBoss实现?
使用一组不同的属性(在JBoss JAX-WS User Guide中找到)使其有效:
//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 :(得分:11)
这是我的工作解决方案:
// --------------------------
// 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 :(得分:9)
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);
这对我有用。
答案 4 :(得分:7)
如果您在JDK6上使用JAX-WS,请使用以下属性:
com.sun.xml.internal.ws.connect.timeout
com.sun.xml.internal.ws.request.timeout
答案 5 :(得分: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调用时,这对我有用。
答案 6 :(得分:3)
如果你的appserver是WebLogic(对我而言是10.3.6),那么负责超时的属性是:
com.sun.xml.ws.connect.timeout
com.sun.xml.ws.request.timeout
答案 7 :(得分:2)
在实例化SEI时避免缓慢检索远程WSDL的最简单方法是在运行时不从远程服务端点检索WSDL。
这意味着您必须在服务提供商进行有影响的更改时更新本地WSDL副本,但这也意味着您必须在服务提供商进行影响更改时更新本地副本。
当我生成客户端存根时,我告诉JAX-WS运行时以这样一种方式注释SEI,即它将从类路径上的预定位置读取WSDL。默认情况下,该位置相对于Service 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 .. etc ..)位于正确的位置。
由于该位置是相对于SEI的包位置,我们创建一个名为wsdl的新子包(目录),并复制那里的所有wsdl工件。
此时您需要做的就是确保在创建客户端 - 存根工件jar文件时,除了所有* .class之外还包括所有* .wsdl,*。xsd。
(如果您好奇,@ webserviceClient注释是这个wsdl位置实际在java代码中设置的地方
@WebServiceClient(name = "httpServices", targetNamespace = "http://www.helter.com/schema/helter/httpServices", wsdlLocation = "./wsdl/helterHttpServices.wsdl")