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

erhoui1w  于 2022-11-15  发布在  其他
关注(0)|答案(8)|浏览(215)

我已经使用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);

我的问题是,不管上面哪一个是正确的,我都不知道 * 在哪里 * 我可以这样做。我得到的只是一个Service子类,它实现了自动生成的Web服务接口,并且在示例化时,如果WSDL没有响应,那么设置属性已经太晚了:

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

谁能给我指个方向?!

g6ll5ycj

g6ll5ycj1#

我知道这是旧的,并回答了其他地方,但希望这关闭了它。我不知道为什么你会想动态下载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);

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

bvuwiixz

bvuwiixz2#

接受的答案中的属性对我不起作用,可能是因为我使用的是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");
66bbxpm5

66bbxpm53#

以下是我的工作解决方案:

// --------------------------
// 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.");

    }
}
jm2pwxwz

jm2pwxwz4#

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);

这对我很有效。

tyg4sfes

tyg4sfes5#

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

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

ev7lccsx6#

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

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

lf5gs5x27#

不确定这对你的背景是否有帮助...
是否可以将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调用超时时,这对我很有效。

mpbci0fu

mpbci0fu8#

在示例化SEI时避免远程WSDL检索缓慢的最简单方法是在运行时不从远程服务端点检索WSDL。
这意味着,每当服务提供者做出影响的更改时,您必须更新本地WSDL副本,但也意味着每当服务提供者做出影响的更改时,您必须更新本地副本。
当我生成客户端桩模块时,我告诉JAX-WS运行时以这样一种方式注解SEI,即它将从类路径上的预定位置读取WSDL。

<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。
(in如果您感到好奇,@webserviceClient注解是在java代码中实际设置此wsdl位置的位置

@WebServiceClient(name = "httpServices", targetNamespace = "http://www.helter.com/schema/helter/httpServices", wsdlLocation = "./wsdl/helterHttpServices.wsdl")

相关问题