代码之家  ›  专栏  ›  技术社区  ›  Sean Patrick Floyd

Spring、CXF:web服务客户机和服务器之间的松耦合

  •  1
  • Sean Patrick Floyd  · 技术社区  · 15 年前

    我有两个webapp:一个web服务客户端和一个服务器(都基于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的接口(名称已更改…),它是客户机和服务器都知道的,上面的客户机定义创建了一个可以使用此接口注入的代理客户机。

    当两个webapp都在运行时,每件事都能很好地工作,特别是当我先部署服务器,然后部署客户端时。但是当服务器webapps不能正确启动时,客户端webapp挂起在一个无限循环中,试图从不存在的WSDL创建代理。

    有没有人对如何实现这个功能有任何指导?服务器是tomcat。在生产过程中,webapps可能部署在同一台服务器上,也可能不部署在同一台服务器上。后端使用spring/jpa/cxf,前端使用spring/wicket。

    2 回复  |  直到 15 年前
        1
  •  2
  •   matt b    15 年前

    与在运行时生成代理不同,听起来您希望离线创建web服务代理/客户机代码。

    作为另一种方法,客户机bean可以指向静态wsdl文件,而不是位于远程服务器上的文件。

        2
  •  1
  •   Community Mohan Dere    8 年前

    尽管静态wsdl创建方法很有前途,但我选择了另一种方法(主要是因为cxfmaven代码生成有缺陷)。

    我将另一个factoryBean包装在现有的factoryBean上,并将其附加到一个服务提供者对象上,该对象定期 pings the wsdl URL for availability . 我在factorybean中的缓存中保存了一个服务代理,一旦它被创建,一旦服务提供者ping失败就删除它。

    如果服务当前不可用,我的FactoryBean会抛出ServiceNotAvailableException。我的前端捕捉到这一点,并显示了一个不错的“服务当前不可用”页面。

    此外,AspectJ方面捕获对服务的所有写入调用,并在服务再次可用时重新调度它们。

    以下是我的spring配置的摘录:

    <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" />
    
    推荐文章