如何为Spring配置的基于Apache CXF的Web服务客户端提供服务器地址?

lex*_*ore 5 java spring web-services cxf

我正在试验Apache CXF,并对客户端部分有疑问.

下面是我目前对某些WS客户端的Spring配置com.example.customerservice.service.CustomerService:

<jaxws:client
    name="com.example.customerservice.service.CustomerServiceClient"
    serviceName="customer:CustomerServiceService" endpointName="customer:CustomerServiceEndpoint"
    address="http://localhost:8080/CustomerServicePort"
    serviceClass="com.example.customerservice.service.CustomerService">
    <jaxws:features>
        <bean class="org.apache.cxf.feature.LoggingFeature" />
    </jaxws:features>
</jaxws:client>
Run Code Online (Sandbox Code Playgroud)

如您所见,该address属性是静态配置的.这不适合我,因为我事先不知道服务器URL.此外,在某些情况下,我想将此客户端用于具有不同地址的不同服务.

因此,Spring中服务器地址的静态配置是不合适的.所以我的问题是 - 我怎样才能让它变得动态?

  • 目前我的解决方案是设置一个系统属性 - 类似于baseUrl并使用属性占位符配置器将其注入Spring配置.
  • 另一种可能性是简单地手动构建客户端,我也不喜欢.

但我相信我真的错过了一些东西.也许有可能出现类似的情况clientFactory.createClientFor("http://myserver:8080")

Dav*_*eri 5

请参阅CXF 用户邮件列表的帖子。

您有几个选择:

1) 如果您想保留 Spring 上下文并在运行时以编程方式更改地址:

您可以在请求上下文中设置标准属性。以下是如何以编程方式执行此操作的示例。

BindingProvider bp = (BindingProvider)port; 地图上下文 = bp.getRequestContext(); Object oldAddress = context.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY); context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, newAddress);

执行此操作时,您应该了解对客户端代理的多线程访问。请参阅 CXF 常见问题解答(JAX-WS 客户端代理线程安全吗?)

2) 如果您愿意/能够提供 WSDL URL 并使用 JAX-WS API,您可以编写可移植代码来创建连接到您选择的端点的客户端代理。您可以在 Spring 上下文文件中使用“createdFromAPI”(配置 Spring 客户端(选项 1))属性,以仍然允许对以编程方式构建的客户端代理进行基于 Spring 的配置。我认为这里也支持通配符,因此您应该能够使用 Spring 上下文中的单个条目配置多个客户端。如果您尝试与之交互的端点之间的端点命名空间/本地名称差异很大,则此方法将变得更加复杂。

3) 以编程方式使用 org.apache.cxf.jaxws.JaxWsProxyFactoryBean,如配置 Spring 客户端(选项 2)[2] 的 Spring 配置所示。这让您可以随意设置接口和地址并创建新的客户端代理实例。您甚至可能希望使用 Spring 中已经设置的大多数属性来配置此工厂的单个实例,然后将其注入您的代码中,您可以在其中更改地址并随意构造一个新的客户端代理(提供对工厂 bean 的同步访问)课程)。您还可以缓存客户端代理以避免重复重新创建它们的费用。

http://cxf.apache.org/faq.html#FAQ-AreJAXWSclientproxiesthreadsafe%253F http://cxf.apache.org/docs/jax-ws-configuration.html

  • 我最终选择通过 jaxWsProxyFactoryBean 以编程方式创建: final JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); jaxWsProxyFactoryBean.setServiceClass(CustomerService.class); jaxWsProxyFactoryBean.setAddress(webAppEnvironment.getBaseUrl() + "/CustomerServicePort"); 就是这样,三行代码。目前足以满足我的目的。 (2认同)