Как установить тайм-аут для клиента JAX-WS webservice?


я использовал 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 81

8 ответов:

Я знаю, что это старый и ответил в другом месте, но, надеюсь, это закрывает это. Я не уверен, почему вы хотите загрузить 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  
com.sun.xml.internal.ws.request.timeout

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

можно ли использовать объект 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 каждый раз, когда поставщик услуг вносит влияющие изменения, но это также означает, что вы должны обновлять свою локальную копию каждый раз, когда поставщик услуг вносит влияющие изменения.

когда я создаю свои клиентские заглушки, я говорю среде выполнения 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 в дополнение ко всем *.класс при создании файла jar артефакта клиент-заглушка.

(в случае вашего любопытства, аннотация @webserviceClient-это то, где это местоположение wsdl фактически установлено в коде java

@WebServiceClient(name = "httpServices", targetNamespace = "http://www.helter.com/schema/helter/httpServices", wsdlLocation = "./wsdl/helterHttpServices.wsdl")

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

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