2010-08-23 2 views
1

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

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

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

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

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

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

ответ

1

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

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

Если услуга в настоящий момент недоступна, мой 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" /> 
2

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

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

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

+0

? Я не вижу разницы между третьим абзацем и остальными. Но да, я согласен, это, вероятно, путь.Однако огромный недостаток заключается в том, что (исправьте меня, если я ошибаюсь) это связывает мой webapp с одним конкретным сервером. В моем предыдущем сценарии я мог развернуть сервер везде, где захочу, и просто изменить системное свойство на клиенте. Но если я создам клиент против WSDL статически, нет чистого способа изменить информацию о сервере. –

+0

@seanizer, предполагая, что вы ссылаетесь на то, что клиентский код будет создан для вызова служб по определенному URL-адресу, это неверно. Сгенерированный код, скорее всего, будет * по умолчанию * для вызова сервисов по URL-адресу, содержащемуся в WSDL, но это переоценивается в каждом генераторе кода клиента веб-сервиса, который я когда-либо видел во время выполнения - например, при создании экземпляра прокси-сервера клиента, который вы передаете URL для использования в нем. –

+0

это звучит хорошо. Я попробую завтра и проверит документы CXF, чтобы посмотреть, как это делается. Благодарю. (+1, кстати) –