开发者

How to provide server address to the Spring-configured Apache CXF-based web service client?

I'm experimenting with Apache CXF and have a question about the client part.

Below is my current Spring configuration of the WS client of some 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>

As you see, the address attribute is configured statically. This is not suitable for me because I don't know the server URL in advance. Moreover, in certain scenarios I'd like to use this client for different services which have different addresses.

Therefore static configuration of the server address in Spring is not appropriate. So my question is - how can I make it dynamic?

  • At the moment my solution is to set a system property - something like baseUrl and inject开发者_运维问答 it into the Spring config using the property placeholder configurer.
  • Another possibility would be to simply construct the client manually which I don't really like either.

But I believe I'm really missing something. Maybe there is a possibility of something like clientFactory.createClientFor("http://myserver:8080")?


See post to CXF Users Mailing List.

You have a couple options:

1) If you want to leave your Spring context as is and change the address programmatically at runtime:

You can set a standard property in the request context. Here is an example of how to do this programmatically.

BindingProvider bp = (BindingProvider)port; Map context = bp.getRequestContext(); Object oldAddress = context.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY); context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, newAddress);

When doing this, you should be aware of multi-threaded access to a client proxy. See the CXF FAQ (Are JAX-WS client proxies thread safe?)

2) If you are willing/able to provide WSDL URLs and use the JAX-WS APIs, you can write portable code that will create a client proxy wired to an endpoint of your choosing. You can use the "createdFromAPI" (Configuring a Spring Client (Option 1)) attribute in your Spring context file to still allow Spring based configuration of the programmatically constructed client proxy. I think that wildcards are also supported here so you should be able to configure a number of clients using a single entry in your Spring context. This approach will get more complex if the endpoint namespaces/local names vary greatly between the endpoints you are trying to interact with.

3) Use org.apache.cxf.jaxws.JaxWsProxyFactoryBean programmatically as shown in the Spring configuration of Configuring a Spring Client (Option 2) [2]. This lets you set the interface and address and create new client proxy instances at will. You may even want to configure a single instance of this factory with most properties already set in Spring and then inject it into your code where you can change the address and construct a new client proxy at will (providing for synchronized access to the factory bean of course). You can also cache the client proxies to avoid the expense of re-creating them repeatedly.

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜