Contact Us 1-800-596-4880

Consuming Web Services with CXF

Mule runtime engine version 3.8 reached its End of Life on November 16, 2021. For more information, contact your Customer Success Manager to determine how to migrate to the latest Mule version.

When sending requests to an external web service, the recommended approach is to use the Web Service Consumer rather than the CXF Module.

This page describes how to consume web services using the CXF client message processors.

There are 4 ways to consume web services. The first 3 correspond to the 3 ways of building web services:

  1. Generate and use a client from a WSDL

  2. Use a client based on the interface of a JAX-WS service

  3. Use a client based on the interface of a "simple" frontend web service

  4. Use the JAX-WS Java client API

The last two options are only usable if you have the Java interface for your service, meaning that their use is normally limited to use within an organization.

WSDL First JAX-WS Client

You can use a CXF-generated client as an outbound endpoint. First, you generate a CXF client using the WSDL to Java tool from CXF or the Maven plugin. (Note: the CXF transport doesn’t support wrapper-style web service method calls. You may need to create a binding file or change the WSDL directly. See the WSDL to Java tool page for more details.)

Next, you configure the client as an outbound endpoint using the following properties:

  • clientClass: The client class generated by CXF, which extends javax.xml.ws.Service.

  • port: The WSDL port to use for communicating with the service

  • wsdlLocation: The location of the WSDL for the service. CXF uses this to configure the client.

  • operation: The operation name to invoke on the web service. The objects that you pass to the outbound router must match the signature of the method for this operation. If your method takes multiple parameters, they must be put in an Object[] array.

Here is a simple example:

<flow name="csvPublisher">
  ...
  <cxf:jaxws-client
         clientClass="org.apache.hello_world_soap_http.SOAPService"
         port="SoapPort"
         wsdlLocation="classpath:/wsdl/hello_world.wsdl"
         operation="greetMe"/>
  <outbound-endpoint address="http://localhost:63081/services/greeter"/>
</flow>

JAX-WS Code First Client

You can also build a client for your JAX-WS services without the need to generate a client from WSDL. To do this, you need a copy of your service interface and all your data objects locally to use. This can simplify consuming web services if you already have access to the code used to build the service.

<flow name="csvPublisher">
  ...
  <cxf:jaxws-client serviceClass="org.example.HelloService" operation="sayHi"/>
  <outbound-endpoint address="http://localhost:63081/services/greeter"/>
</flow>

Using the JAX-WS Client API

This section describes how to use the JAX-WS client APIs to talk to web services. This allows you to talk to web services outside of mule configurations.

There are two ways to use CXF clients. First, you can generate a client from WSDL using the CXF WSDL to Java tool. Second, if you’ve built your service via "code-first" methodologies, you can use the service interface to build a client proxy object.

When using a CXF client, it automatically discovers the Mule instance (provided you’re in the same JVM/Classloader) and uses it for your transport. Therefore, if you’ve generated a client from WSDL, invoking a service over Mule can be as simple as the following:

HelloWorldService service = new HelloWorldService();
HelloWorld hello = service.getSoapPort();

// Possibly set an alternate request URL:
// ((BindingProvider) greeter).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
                                                       "http://localhost:63081/greeter");
String sayHi = hello.sayHi();

Building a Client Proxy

The following is an example of how to construct a client using the service that was developed in Building Web Services with CXF:

QName SERVICE_NAME = new QName("http://server.hw.demo/", "HelloWorld");
QName PORT_NAME = new QName("http://server.hw.demo/", "HelloWorldPort");

Service service = Service.create(SERVICE_NAME);

// Endpoint Address
String endpointAddress = http://localhost:63081/hello";

// Add a port to the Service
service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);

HelloWorld hw = service.getPort(HelloWorld.class);

System.out.println(hw.sayHi("World"));

Simple Frontend Clients

You can build a client for your simple frontend based services with out the need to generate a client from WSDL. To do this, you need a copy of your service interface and all your data objects locally to use. This can simplify consuming web services if you already have access to the code used to build the service.

<flow name="csvPublisher">
  ...
  <cxf:simple-client serviceClass="org.example.HelloService" operation="sayHi"/>
  <outbound-endpoint address="http://localhost:63081/services/greeter"/>
</flow>