Как установить время ожидания для клиента веб-сервиса JAX-WS? - PullRequest
85 голосов
/ 27 января 2010

Я использовал 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();

Кто-нибудь может указать мне правильное направление?!

Ответы [ 8 ]

82 голосов
/ 04 октября 2010

Я знаю, что это старо и ответили в другом месте, но, надеюсь, это закроет это. Я не уверен, почему вы хотите загружать 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);

Конечно, это ужасный способ сделать что-то, я бы создал хорошую фабрику для производства этих провайдеров связывания, в которые можно вводить желаемое время ожидания.

33 голосов
/ 06 августа 2014

Свойства в принятом ответе у меня не сработали, возможно, из-за того, что я использую реализацию JAX-WS JBoss?

Использование другого набора свойств (см. Руководство пользователя 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");
11 голосов
/ 01 декабря 2010

Вот мое рабочее решение:

// --------------------------
// 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 голосов
/ 15 июля 2011
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);

Это сработало для меня.

7 голосов
/ 15 ноября 2010

Если вы используете JAX-WS на JDK6, используйте следующие свойства:

com.sun.xml.internal.ws.connect.timeout  
com.sun.xml.internal.ws.request.timeout
4 голосов
/ 26 апреля 2018

Если ваш сервер приложений WebLogic (для меня это был 10.3.6), то свойства, ответственные за тайм-ауты:

com.sun.xml.ws.connect.timeout 
com.sun.xml.ws.request.timeout
3 голосов
/ 10 июня 2010

Не уверен, поможет ли это в вашем контексте ...

Может ли объект мыла быть приведен как 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.

2 голосов
/ 26 июня 2010

Самый простой способ избежать медленного извлечения удаленного WSDL при создании экземпляра SEI - не извлекать WSDL из конечной точки удаленной службы во время выполнения.

это означает, что вы должны обновлять свою локальную копию WSDL каждый раз, когда поставщик услуг вносит существенные изменения, но это также означает, что вы должны обновлять свою локальную копию каждый раз, когда поставщик услуг вносит существенные изменения.

Когда я генерирую свои клиентские заглушки, я говорю среде выполнения JAX-WS аннотировать SEI таким образом, чтобы он считывал WSDL из заранее определенного местоположения на пути к классам. по умолчанию расположение относительно расположения пакета службы 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")
...