In order to use the Camel CXF Component to either consume from or produce to SOAP web services, you will first need to generate a set of interfaces that define the web service based on a predefined service contract—the WSDL. To do this, we will use a Maven plugin provided by the Apache CXF project.
These generated interfaces take the form of regular Java classes and interfaces marked up with JAX-WS annotations. These classes, used as arguments and return values from the web service methods, are known as models, and they will be generated from the XML schema contained within the WSDL. These classes will be annotated with JAXB bindings to automate the conversion between the Java objects and their XML representation.
Collectively these JAX-WS artifacts make it possible for Camel to call web services or to act as a web service provider.
This recipe will show you the basics of setting up the cxf-codegen-plugin
to automate the build-time generation of JAX-WS artifacts from your project's WSDL documents.
The cxf-codegen-plugin
is referenced within a Maven project's pom.xml
file. This recipe defines a child project, ws-payments-api
, within the camel-cookbook-web-services
module for the sole purpose of generating JAX-WS artifacts from the WSDL files that define a web service contract. This project's JAR artifact will be used as a dependency by the ws-camel-routes
project that includes the Camel routes.
To generate a class representation of a web service, you will require a WSDL file. This chapter makes use of the samples contained within the src/main/resources/wsdl
directory.
In the Maven project's pom.xml
file, add the following plugin definition:
<build> <plugins> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>${cxf-version}</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>wsdl2java</goal> </goals> <configuration> <sourceRoot> ${project.build.directory}/generated-sources/cxf </sourceRoot> <wsdlRoot> ${project.basedir}/src/main/resources/wsdl </wsdlRoot> <includes> <include>*.wsdl</include> </includes> </configuration> </execution> </executions> </plugin> <!-- other plugins --> </plugins> <!-- other build configurations --> </build>
The ${cxf-version}
used in this example is 2.7.7.
The default behavior of the cxf-codegen-plugin
, as shown configured in the preceding How to do it... section, is to parse the WSDL files in your project's src/main/resources/wsdl
directory (specified in the wsdlRoot
option), and generate JAX-WS and JAXB artifacts in your project's target/generated-sources/cxf
(sourceRoot
) directory.
The code generation happens during the generate-sources
phase of the build (see the Maven documentation for a description of the build lifecycle). Maven will automatically compile these Java source files and include the resulting classes in the module being built. You can then start referencing these classes in your code, including within your Camel routes.
It is considered best practice to create a separate Maven project for the sole purpose of generating the JAX-WS annotated web service API from your WSDL files. This project is then used as a dependency by modules that define your Camel routes. Aside from enabling reuse of the API between modules, it makes the generated classes easier to work with from within an IDE. That is, after the first build of the API project, you get code completion around the generated classes in dependent modules without needing to do anything special in the IDE. This is preferable to doing everything in the same project, as your IDE otherwise depends on a source directory that appears only during a Maven build.
The primary benefit of generating JAX-WS source code from a WSDL, and using it in your Camel routes, is that the body and headers of the SOAP messages are accessible to your routing logic as Plain Old Java Objects (POJOs). This makes it very easy to create routes that work with messages coming from multiple frontend technologies, including web services, and operate on them in a consistent fashion.
Code is generated into packages named in the reverse order of their namespace URIs. Two namespaces are of particular interest, the targetNamespace
for the service definition and the schema namespace of the payload elements. Consider this fragment from the example WSDL file paymentService.wsdl
located in src/main/resources/wsdl/
:
<wsdl:definitions name="wsdl-first" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.camelcookbook.org/payment-service" xmlns:typens= "http://ws.camelcookbook.org/payment-service/types" targetNamespace= "http://ws.camelcookbook.org/payment-service"> <wsdl:types> <xsd:schema targetNamespace= "http://ws.camelcookbook.org/payment-service/types" elementFormDefault="qualified"> <!-- ... --> </xsd:schema> </wsdl:types> <!-- ... --> <wsdl:service name="PaymentService"> <wsdl:port binding="tns:PaymentSOAPBinding" name="PaymentPort"> <soap:address location="http://localhost:9090/paymentService"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
The service interfaces will be generated from the namespace:
http://ws.camelcookbook.org/payment-service
The Java package that they will be placed into is as follows:
org.camelcookbook.ws.payment-service
Likewise, the object representation of the schema will be generated from the following namespace:
http://ws.camelcookbook.org/payment-service/types
The Java package that they will be placed into is as follows:
org.camelcookbook.ws.payment-service.types
You do not have to use the cxf-codegen-plugin
to generate the required JAX-WS annotated objects; you can instead handcode the JAX-WS classes directly using annotations if you like. Alternatively, the Apache CXF project also includes a java2ws
tool that comes with an associated wrapper Maven plugin, which will generate the JAX-WS artifacts from your existing Java interfaces for a service-first approach.
cxf-codegen-plugin
documentation: http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html3.129.210.91