90 votes

Comment définir le délai d'attente pour un client de service Web JAX-WS ?

J'ai utilisé JAXWS-RI 2.1 pour créer une interface pour mon service web, basée sur un WSDL. Je peux interagir avec le service web sans problème, mais je n'ai pas été en mesure de spécifier un délai d'attente pour l'envoi de demandes au service web. Si, pour une raison quelconque, il ne répond pas, le client semble tourner en rond pour toujours.

En cherchant un peu, j'ai découvert que je devrais probablement essayer de faire quelque chose comme ça :

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

J'ai également découvert que, selon la version de JAXWS-RI dont vous disposez, vous devrez peut-être définir ces propriétés à la place :

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

Le problème que j'ai, c'est qu'indépendamment de ce qui précède, je ne sais pas Je peux le faire. Tout ce que j'ai, c'est un Service qui implémente l'interface générée automatiquement pour le webservice. Au moment où cette classe est instanciée, si le WSDL ne répond pas, il est déjà trop tard pour définir les propriétés :

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

Quelqu'un peut-il m'indiquer la bonne direction ?

85voto

alpian Points 3002

Je sais que cette question est ancienne et qu'on y a répondu ailleurs, mais j'espère qu'elle sera résolue. Je ne vois pas pourquoi vous voudriez télécharger le WSDL de façon dynamique, mais les propriétés du système :

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

devrait s'appliquer à toutes les lectures et connexions utilisant HttpURLConnection que JAX-WS utilise. Cela devrait résoudre votre problème si vous obtenez la WSDL à partir d'un emplacement distant - mais un fichier sur votre disque local est probablement mieux !

Ensuite, si vous voulez définir des délais d'attente pour des services spécifiques, une fois que vous avez créé votre proxy, vous devez le convertir en un BindingProvider (que vous connaissez déjà), obtenir le contexte de la requête et définir vos propriétés. La documentation JAX-WS en ligne est erronée, ce sont les noms de propriétés corrects (enfin, ils fonctionnent pour moi).

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

Bien sûr, c'est une façon horrible de faire les choses, je créerais une belle usine pour produire ces fournisseurs de liaison qui peuvent être injectés avec les délais que vous voulez.

36voto

jwaddell Points 542

Les propriétés indiquées dans la réponse acceptée n'ont pas fonctionné pour moi, peut-être parce que j'utilise l'implémentation JBoss de JAX-WS ?

En utilisant un ensemble différent de propriétés (que l'on trouve dans la section Guide de l'utilisateur de JBoss JAX-WS ) l'ont fait fonctionner :

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

12voto

vnoel Points 59

Voici ma solution de travail :

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

    }
}

10voto

tieTYT Points 15326
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);

Cela a marché pour moi.

8voto

dometec Points 71

Si vous utilisez JAX-WS sur JDK6, utilisez les propriétés suivantes :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X