【问题标题】:Spring, CXF: Loose coupling between web service client and serverSpring,CXF:Web 服务客户端和服务器之间的松散耦合
【发布时间】:2010-08-23 13:55:06
【问题描述】:

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

当两个 web 应用程序都运行时,一切都运行良好,特别是当我先部署服务器然后部署客户端时。但是当服务器 webapps 没有正确启动时,客户端 webapp 会陷入无限循环,试图从不存在的 WSDL 创建代理。

基本上我想要的是一个围绕服务代理的代理,它让调用在服务可用时通过,并在服务关闭时引发足够的异常,我可以捕获并显示“抱歉,我们”重新脱机”页面,并在 Web 服务再次可用时恢复服务。我可以通过构建过程以静态形式访问 WSDL(通过 cxf maven 插件自动生成),因此我可以将其用于初始配置,因此从这个角度来看,我独立于服务器。

是否有人对如何实现此功能有任何指示?服务器是tomcat。在生产过程中,Web 应用程序可能会或可能不会部署到同一台服务器上。后端使用spring/jpa/cxf,前端使用spring/wicket。

【问题讨论】:

    标签: java web-services spring soap cxf


    【解决方案1】:

    听起来您想离线创建 Web 服务代理/客户端代码,而不是在运行时生成代理。

    我不确定 CXF 是如何处理这个问题的,但是您可以使用 wsdl2java 之类的工具为给定的 wsdl 文档生成 Web 服务客户端代码。

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

    【讨论】:

    • ?我看不出第三段和其余段之间的区别。但是,是的,我同意,这可能是要走的路。然而,最大的缺点是(如果我错了,请纠正我)这将我的 webapp 绑定到一个特定的服务器。在我之前的场景中,我可以将服务器部署在我想要的任何地方,并且只需更改客户端上的系统属性。但是,如果我针对 WSDL 静态构建客户端,则没有干净的方法可以更改服务器信息。
    • @seanizer,假设您指的是将生成客户端代码以调用特定 URL 上的服务,这是不正确的。生成的代码可能默认针对 WSDL 中包含的 URL 调用服务,但这在我在运行时见过的每个 Web 服务客户端代码生成器中都是可覆盖的 - 例如,当您实例化您将要使用的 URL 传递给客户端代理。
    • 听起来不错。明天我会试一试,并查看 CXF 文档以了解它是如何完成的。谢谢。 (+1,顺便说一句)
    【解决方案2】:

    虽然静态 wsdl 创建方法很有希望,但我选择了另一种(主要是因为 cxf maven 代码生成有问题)。

    我在现有的 factoryBean 周围包裹了另一个 factoryBean,并将它附加到一个定期 pings the wsdl URL for availability 的服务提供者对象。我将服务代理保存在工厂 bean 内的缓存中,一旦创建,就会在服务提供者 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" />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-30
      • 2011-02-10
      • 2016-10-22
      • 2018-11-19
      • 2023-03-12
      • 2011-12-27
      相关资源
      最近更新 更多