webservicefeature jaxws jax asincrono java web-services soap timeout jax-ws

java - jaxws - ¿Cómo configuro el tiempo de espera para un cliente de servicio web JAX-WS?



web service connection timeout java (8)

He usado JAXWS-RI 2.1 para crear una interfaz para mi servicio web, basado 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 parece girar las ruedas para siempre.

La búsqueda ha revelado que probablemente debería intentar 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 la versión de JAXWS-RI que tenga, es posible que deba 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 sea correcto, no sé dónde puedo hacer esto. Todo lo que tengo es una subclase de Service que implementa la interfaz autogenerada para el servicio web y en el momento en que 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();

¿Alguien puede señalarme en la dirección correcta?


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


En caso de que su servidor de aplicaciones sea WebLogic (para mí fue 10.3.6), las propiedades responsables de los tiempos de espera son:

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


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

esto significa que debe actualizar su copia WSDL local en cualquier momento en que el proveedor del servicio tenga un cambio impactante, pero también significa que debe actualizar su copia local cada vez que el proveedor del servicio tenga un cambio impactante.

Cuando genero mis apéndices de cliente, le digo al tiempo de ejecución de JAX-WS que haga una anotación en el SEI de tal forma que lea 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 de xsd ... etc.) se encuentre en la ubicación correcta.

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

todo lo que tiene que hacer en este momento es asegurarse de incluir todos * .wsdl, * .xsd además de todos los * .class cuando cree su archivo jar de artifact de stub de cliente.

(en caso de que tenga 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")


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

Usar un conjunto diferente de propiedades (que se encuentra 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");


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

¿Se puede lanzar el objeto de jabón como un proveedor de encuadernación?

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 agotar el tiempo de las llamadas individuales de WebService.


Sé que esto es viejo y respondido en otro lugar, pero espero que esto lo cierre. No estoy seguro de por qué desea 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 conectarse utilizando HttpURLConnection que utiliza JAX-WS. Esto debería resolver su problema si obtiene el WSDL desde una ubicación remota, ¡pero probablemente sea mejor un archivo en su disco local!

A continuación, si desea establecer tiempos de espera para servicios específicos, una vez que haya creado su proxy, debe convertirlo a un proveedor de enlace (que ya conoce), obtener el contexto de 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 manera horrible de hacer las cosas, crearía una buena fábrica para producir estos proveedores vinculantes que pueden inyectarse con los tiempos de espera que desee.


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

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


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í.