Я использовал JAXWS-RI 2.1 для создания интерфейса для моей веб-службы на основе WSDL. Я могу взаимодействовать с веб-службой без проблем, но не могу указать тайм-аут для отправки запросов к веб-службе. Если по какой-то причине он не отвечает, клиент просто крутит колеса вечно.
Поиски вокруг показали, что мне, вероятно, следует попробовать сделать что-то вроде этого:
((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
подкласс, который реализует автоматически сгенерированный интерфейс для веб-сервиса, и в момент создания его экземпляра, если WSDL не отвечает, тогда уже слишком поздно устанавливать свойства:
MyWebServiceSoap soap;
MyWebService service = new MyWebService("http://www.google.com");
soap = service.getMyWebServiceSoap();
soap.sendRequestToMyWebService();
Может кто-то указать мне верное направление?!
Ответы:
Я знаю, что это устарело и ответил в другом месте, но, надеюсь, это закрывает это. Я не уверен, почему вам нужно динамически загружать WSDL, но свойства системы:
sun.net.client.defaultConnectTimeout (default: -1 (forever)) sun.net.client.defaultReadTimeout (default: -1 (forever))
должен применяться ко всем операциям чтения и подключения с использованием HttpURLConnection, который использует JAX-WS. Это должно решить вашу проблему, если вы получаете 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);
Конечно, это ужасный способ делать что-то, я бы создал хорошую фабрику для создания этих поставщиков привязки, которые можно вводить с нужными вам таймаутами.
источник
Свойства в принятом ответе у меня не сработали, возможно, потому, что я использую JBoss-реализацию JAX-WS?
Используя другой набор свойств (найденный в Руководстве пользователя JBoss JAX-WS ) заставило его работать:
//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");
источник
Вот мое рабочее решение:
// -------------------------- // 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."); } }
источник
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);
Это сработало для меня.
источник
Если вы используете JAX-WS на JDK6, используйте следующие свойства:
источник
com.sun.xml.internal.ws.connect.timeout
vscom.sun.xml.ws.connect.timeout
), а также класс (или интерфейс), который их определяет (com.sun.xml.internal.ws.developer.JAXWSProperties
/com.sun.xml.internal.ws.client.BindingProviderProperties
vscom.sun.xml.ws.developer.JAXWSProperties
/com.sun.xml.ws.client.BindingProviderProperties
). Моя лучшая идея - установить оба, используя буквальные значения в качестве ключей.Если ваш сервер приложений - это WebLogic (для меня это было 10.3.6), то свойства, отвечающие за тайм-ауты, следующие:
источник
Не уверен, поможет ли это в вашем контексте ...
Можно ли преобразовать объект 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.
источник
Самый простой способ избежать медленного извлечения удаленного WSDL при создании экземпляра SEI - не извлекать 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 ... и т. д.) находится в правильном месте.
поскольку это расположение относительно расположения пакета SEI, мы создаем новый подпакет (каталог) с именем wsdl и копируем туда все артефакты wsdl.
все, что вам нужно сделать на этом этапе, это убедиться, что вы включили все * .wsdl, * .xsd в дополнение ко всем * .class, когда вы создаете файл jar артефакта клиент-заглушки.
(на случай, если вам интересно, аннотация @webserviceClient - это то место, где это местоположение wsdl фактически установлено в java-коде
@WebServiceClient(name = "httpServices", targetNamespace = "http://www.helter.com/schema/helter/httpServices", wsdlLocation = "./wsdl/helterHttpServices.wsdl")
источник