¿Cómo establezco el tiempo de espera para un cliente webservice JAX-WS?


He usado JAXWS-RI 2.1 para crear una interfaz para mi servicio web, basada en un WSDL. Puedo interactuar con el servicio web sin problemas, pero no he podido especificar un tiempo de espera para enviar solicitudes al servicio web. Si por alguna razón no responde el cliente solo parece girar sus ruedas para siempre.

La caza alrededor ha revelado que probablemente debería estar tratando de hacer algo como esto:

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

También descubrí que, dependiendo de qué versión de JAXWS-RI tener, es posible que necesite establecer estas propiedades en su lugar:

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

El problema que tengo es que, independientemente de cuál de los anteriores es correcto, no se dónde puedo hacer esto. Todo lo que tengo es un Service subclase que implementa la interfaz generada automáticamente en el servicio web y en el punto en que esto se está instanciando, si el WSDL no responde, ya es demasiado tarde para establecer las propiedades:

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

¿Puede alguien señalarme en la dirección correcta?!

Author: Jon Seigel, 2010-01-27

8 answers

Sé que esto es viejo y respondió en otra parte, pero espero que esto cierre esto. No estoy seguro de por qué querría descargar el WSDL dinámicamente, pero las propiedades del sistema:

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

Debería aplicarse a todas las lecturas y conexiones usando HttpURLConnection que usa JAX-WS. Esto debería resolver su problema si está obteniendo el WSDL desde una ubicación remota, ¡pero un archivo en su disco local probablemente sea mejor!

A continuación, si desea establecer tiempos de espera para servicios específicos, una vez que haya creado su proxy necesita enviarlo a un BindingProvider (que ya conoce), obtener el contexto de la solicitud y establecer sus propiedades. La documentación en línea de JAX-WS es incorrecta, estos son los nombres de propiedad correctos (bueno, funcionan para mí).

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

Por supuesto, esta es una forma horrible de hacer las cosas, crearía una buena fábrica para producir estos proveedores de enlace que se pueden inyectar con los tiempos de espera que desee.

 79
Author: alpian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-03 22:11:32

Las propiedades en la respuesta aceptada no funcionaron para mí, posiblemente porque estoy usando la implementación de JBoss de JAX-WS?

Usando un conjunto diferente de propiedades (que se encuentran en la Guía del usuario de JBoss JAX-WS ) lo hizo funcionar:

//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");
 31
Author: jwaddell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-06 04:45:56

Aquí está mi solución de trabajo:

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

    }
}
 9
Author: vnoel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-01 10:05:27
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);

Esto funcionó para mí.

 7
Author: Daniel Kaplan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-14 21:37:24

Si está utilizando JAX-WS en JDK6, utilice las siguientes propiedades:

com.sun.xml.internal.ws.connect.timeout  
com.sun.xml.internal.ws.request.timeout
 6
Author: Domenico Briganti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-06 19:50:15

No estoy seguro de si esto ayudará en su contexto...

¿Se puede convertir el objeto soap como un 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();

Por otro lado, si desea establecer el tiempo de espera en la inicialización del objeto MyWebService, esto no ayudará.

Esto funcionó para mí cuando quería timeout las llamadas individuales al servicio WEB.

 3
Author: Ron Tuffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-10 11:47:34

La forma más fácil de evitar la recuperación lenta del WSDL remoto cuando instancie su SEI es no recuperar el WSDL desde el punto final del servicio remoto en tiempo de ejecución.

Esto significa que usted tiene que actualizar su WSDL local copiar cualquier momento el proveedor de servicios impactante cambio, pero también significa que usted tiene que actualizar su copia local en cualquier momento el proveedor de servicios impactante cambio.

Cuando genero mis stubs de cliente, le digo al tiempo de ejecución de JAX-WS que anote SEI de tal manera que leerá el WSDL desde una ubicación predeterminada en el classpath. de forma predeterminada, la ubicación es relativa a la ubicación del paquete del Servicio 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>

El atributo wsldLocation le dice al SEI dónde puede encontrar el WSDL, y la copia se asegura de que el wsdl (y el soporte xsd.. sucesivamente..) está en la ubicación correcta.

Dado que la ubicación es relativa a la ubicación del paquete del SEI, creamos un nuevo subpaquete (directorio) llamado wsdl, y copiar todos los artefactos wsdl allí.

Todo lo que tiene que hacer en este punto es asegurarse de incluir todos *.wsdl, *.xsd además de todos*.clase al crear su archivo jar de artefacto de cliente-stub.

(en caso de curiosidad, la anotación @webserviceClient es donde esta ubicación wsdl se establece realmente en el código java

@WebServiceClient(name = "httpServices", targetNamespace = "http://www.helter.com/schema/helter/httpServices", wsdlLocation = "./wsdl/helterHttpServices.wsdl")
 2
Author: Helter Scelter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-25 20:33:44

En caso de que tu appserver sea WebLogic (para mí era 10.3.6), las propiedades responsables de los tiempos de espera son:

com.sun.xml.ws.connect.timeout 
com.sun.xml.ws.request.timeout
 2
Author: E.Egiazarov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-26 16:33:38