Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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")?

like image 416
lexicore Avatar asked Apr 20 '10 21:04

lexicore


People also ask

Where do I put CXF XML?

For both web service clients and servers, the default location that CXF will look for a configuration for is "/cxf. xml" on the class path. For example, when running your application in a servlet container, this file is expected to be located in a /WEB-INF/classes folder of your web application.

How does Apache CXF work?

Apache CXF™ is an open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.

What is spring CXF?

Apache CXF and Spring are primarily classified as "Composable Web Service Framework" and "Frameworks (Full Stack)" tools respectively. Spring is an open source tool with 31.2K GitHub stars and 20.1K GitHub forks. Here's a link to Spring's open source repository on GitHub.

What is CXF endpoint?

In Apache Camel, the Camel CXF component is the key to integrating routes with Web services. You can use the Camel CXF component to create a CXF endpoint, which can be used in either of the following ways: Consumer — (at the start of a route) represents a Web service instance, which integrates with the route.


1 Answers

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

like image 194
DavidValeri Avatar answered Sep 24 '22 18:09

DavidValeri