Spring, CXF: слабая связь между клиентом веб-службы и сервером - PullRequest
1 голос
/ 23 августа 2010

У меня есть два веб-приложения: клиент веб-службы и сервер (оба на основе CXF с использованием подхода Simple Front-End ).

Это определение сервера:

<simple:server id="server" bindingId="http://schemas.xmlsoap.org/soap/"
    address="/thingy" transportId="http://schemas.xmlsoap.org/soap/"
    serviceName="cs:thingyService"
    serviceClass="com.mycompany.thingy.api.service.ThingyService"
    endpointName="cs:thingyServicePort">
        <simple:serviceBean>
            <bean class="com.mycompany.thingy.server.service.ThingyServiceDelegate">
                <property name="thingyService" ref="thingyService"></property>
            </bean>
        </simple:serviceBean>

        <simple:dataBinding>
            <bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
        </simple:dataBinding>
        <simple:binding>
            <soap:soapBinding version="1.1" mtomEnabled="true" />
        </simple:binding>
</simple:server>

А вот клиент:

<http-conf:conduit name="*.http-conduit">
    <http-conf:client AllowChunking="false" />
</http-conf:conduit>

<simple:client id="thingyService" wsdlLocation="${wsdl.url}?wsdl"
    serviceName="cs:thingyService"
    endpointName="cs:thingyServicePort"
    transportId="http://schemas.xmlsoap.org/soap/"
    address="${wsdl.url}"
    bindingId="http://schemas.xmlsoap.org/soap/"
    serviceClass="com.mycompany.thingy.api.service.ThingyService">
        <simple:dataBinding>
            <bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
        </simple:dataBinding>
        <simple:binding>
            <soap:soapBinding mtomEnabled="true" version="1.1" />
        </simple:binding>
</simple:client>

У меня есть интерфейс под названием ThingyService (имена были изменены ...), который известен как клиенту, так и серверу, а также указанному выше клиенту.Definition создает прокси-клиент, который можно внедрить с помощью этого интерфейса.

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

По сути, мне нужен прокси-сервер вокруг сервисного прокси, которыйпропускает вызовы, когда служба доступна, и выдает соответствующее исключение, когда служба не работает, которую я могу поймать и показать страницу «извините, мы не в сети» в графическом интерфейсе и возобновляет службу, когда веб-служба снова становится доступной,У меня есть доступ к WSDL в статической форме через процесс сборки (сгенерированный автоматически с помощью плагинов cxf maven), так что я могу использовать его для начальной конфигурации, поэтому с этой точки зрения я не зависим от сервера.

Есть ли у кого-нибудь указания, как реализовать эту функцию?Сервер является котом.Веб-приложения могут или не могут быть развернуты на одном сервере во время производства.В бэкэнде используется пружина / jpa / cxf, в переднем конце - пружина / калитка.

Ответы [ 2 ]

2 голосов
/ 23 августа 2010

Вместо генерации прокси во время выполнения кажется, что вы хотите создать прокси / код клиента веб-сервиса в автономном режиме.

Я не уверен, как это обрабатывается в CXF, но вы можете использовать такие инструменты, как wsdl2java, чтобы сгенерировать код клиента веб-службы для данного документа wsdl.

В качестве альтернативного подхода клиентский компонент может быть направлен на статический файл wsdl, а не на удаленный сервер.

1 голос
/ 30 августа 2010

Хотя подход к созданию статического wsdl был многообещающим, я выбрал другой (в основном из-за того, что генерация кода cxf maven содержит ошибки).

Я обернул другой factoryBean вокруг существующего и прикрепил его к объекту поставщика услуг, который регулярно пингует URL-адрес wsdl для доступности . Я храню прокси-сервер службы в кэше внутри фабричного компонента, как только он создан, и удаляю его, как только сбой проверки связи поставщика услуг.

Если служба в данный момент недоступна, мой FactoryBean генерирует исключение ServiceNotAvailableException. Мой интерфейс ловит это и показывает приятную страницу "Сервис в настоящее время недоступен".

Кроме того, аспект AspectJ перехватывает все вызовы записи в службу и перепланирует их, когда служба снова становится доступной.

Вот выдержка из моей весенней конфигурации:

<bean id="outerFactoryBean">
    <property name="innerFactory">
        <bean class="org.apache.cxf.frontend.ClientProxyFactoryBean">
             <!-- translation of spring:client definition from question -->
        </bean>
    </property>
    <property name="serviceProvider" ref="serviceProvider" />
</bean>
<bean id="serviceProvider" class="de.mytoys.shop.coupons.web.client.ServiceProvider">
    <property name="wsdlUrl" value="${wsdl.url}?wsdl" />
    <property name="connectionFactory">
        <bean class="org.apache.cxf.transport.http.HttpURLConnectionFactoryImpl" />
    </property>
</bean>

<task:scheduled-tasks>
    <task:scheduled ref="serviceProvider" method="checkAvailability"
        fixed-delay="1000" />
</task:scheduled-tasks>

<task:scheduler id="scheduler" pool-size="1" />
...