CXF WSDL first

Published: Wednesday, 9 June 2010

CXF: WSDL first

Contract first development is where you define the WSDL before writing any Java code.

Here are some quick steps to get started.

Create the WSDL

Save the following in src/main/wsdl/Sample.wsdl

<definitions targetNamespace="http://cxf.sample.magicmonster.com"
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:xs="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:sample="http://cxf.sample.magicmonster.com">

  <import namespace="http://cxf.sample.magicmonster.com" location="sample.xsd"/>
  <message name="EchoInput">
    <part name="body" type="sample:EchoInputMessage"/>
  </message>
  <message name="EchoOutput">
    <part name="body" element="sample:EchoOutputMessage"/>
  </message>
  <portType name="SampleEchoServicePortType">
    <operation name="SampleEchoService">
      <input message="sample:EchoInput"/>
      <output message="sample:EchoOutput"/>
    </operation>
  </portType>
  <binding name="SampleEchoServiceBinding" type="sample:SampleEchoServicePortType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="SampleEchoService">
      <soap:operation soapAction="Sample"/>
      <input>
        <soap:body parts="body" use="literal"/>
      </input>
      <output>
        <soap:body parts="body" use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="SampleEchoService">
    <port name="SampleEchoServicePortType" binding="sample:SampleEchoServiceBinding">
      <soap:address location="http://cxf.sample.magicmonster.com"/>
    </port>
  </service>
</definitions>

Note that is refers to an external xsd, save the following as src/main/wsdl/sample.xsd

This sample XSD shows how you can nest complex types

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://cxf.sample.magicmonster.com"
            xmlns:tns="http://cxf.sample.magicmonster.com">
  <xsd:import namespace="http://www.w3.org/2001/XMLSchema"/>

  <xsd:complexType name="EchoInputMessage">
    <xsd:sequence>
      <xsd:element name="name" type="xsd:string"/>
      <xsd:element name="phoneNumbers" type="tns:PhoneNumberType" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="PhoneNumberType">
    <xsd:sequence>
      <xsd:element name="description" type="xsd:string"/>
      <xsd:element name="number" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:element name="EchoOutputMessage" type="xsd:string"/>
</xsd:schema>

Add to maven build

Add the CXF version property.

  <properties>
    <cxf.version>2.2.8</cxf.version>
  </properties>

Edit your pom.xml, and add to build/plugins/

  <plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>${cxf.version}</version>
    <executions>
      <execution>
        <id>generate-sources</id>
        <phase>generate-sources</phase>
        <configuration>
          <!--<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>-->
          <wsdlOptions>
            <wsdlOption>
              <wsdl>${basedir}/src/main/wsdl/Sample.wsdl</wsdl>
            </wsdlOption>
          </wsdlOptions>
        </configuration>
        <goals>
          <goal>wsdl2java</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

The port type interface, and Java classes representing the XSDs elements will be found in target/generated-sources/cxf.

You can override where this is created by defining the sourceRoot.