Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Excerpt

In this post I will describe how to do contract first in a very simple and efficient way. All people involved in webservice design have the problem what tool to use to describe the webservice interface. Of course there are wsdl editors but you can make many errors in using them and they are normally not very intuitive.

 

The original post is from Christian Schneider´s blog and can be found here

What we would like to have

...

Code Block
java
java
package com.example.customerservice;

@XmlAccessorType( XmlAccessType.FIELD )
public class Customer {
   String name;
   String\[\] address;
   int numOrders;
   double revenue;
   BigDecimal test;
   Date birthDate;
   CustomerType type;
}

The sample class Customer gives a nice overview which primitive datatypes can be used. Additionally you can create arrays of primitive or class datatypes in this way. The complete example also contains an enumeration definition to show this is possible. I think this code is quite near the DSL I would imagine to describe my services.The enumeration

Enumeration CustomerType

Shows shows how enumerations are handled:

Code Block
java
java
package com.example.customerservice;

public enum CustomerType {
   PRIVATE, BUSINESS
}

NoSuchCustomerException

 Defining Exceptions is a little tricky as the default behaviour is to create Exception_Exception classes in the later generated Java code. So we have to use the @WebFault annotation to give the Bean for the data a name that is separate from the Exception name.

Code Block

package com.example.customerservice;

@WebFault(name="NoSuchCustomer")
@XmlAccessorType( XmlAccessType.FIELD )
public class NoSuchCustomerException extends RuntimeException {
	/**
	 * We only define the fault details here. Additionally each fault has a message
	 * that should not be defined separately
	 */
	String customerName;
}

Service definition

Code Block
java
java
package com.example.customerservice;

@WebService
public interface CustomerService {
public Customer[] getCustomersByName(@WebParam(name="name") String name) throws NoSuchCustomerException;
}

As you can see only two annotations are necessary here. @WebService marks the interface as a service and @Webparam is necessary as Java will else loose the name of the parameter and the wsdl will contain arg0 instead of the desired name. Using the @WebService annotation you can also customize the port name and service name.

How is the wsdl generated

...

You can download the wsdl this example creates here\.

Code Block
xml
xml
<xs:complexType name="customer">
 &nbsp; <xs:sequence>
    &nbsp;&nbsp;&nbsp; <xs:element minOccurs="0" name="name" type="xs:string"/>
    &nbsp;&nbsp;&nbsp; <xs:element maxOccurs="unbounded" minOccurs="0" name="address" nillable="true" type="xs:string"/>
    &nbsp;&nbsp;&nbsp; <xs:element name="numOrders" type="xs:int"/>
    &nbsp;&nbsp;&nbsp; <xs:element name="revenue" type="xs:double"/>
   &nbsp;&nbsp;&nbsp; <xs:element minOccurs="0" name="test" type="xs:decimal"/>
    &nbsp;&nbsp;&nbsp; <xs:element minOccurs="0" name="birthDate" type="xs:dateTime"/>
   &nbsp;&nbsp;&nbsp; <xs:element minOccurs="0" name="type" type="tns:customerType"/>
&nbsp;  </xs:sequence>
</xs:complexType>

...

The array of Strings for address is described as maxOccurs="unbounded" so the element may be repeated in the later xml to form the array.

Enumeration customerType

The enumeration customerType is described as a simple type with a restriction:

Code Block
xml
xml
<xs:simpleType name="customerType">
 &nbsp; <xs:restriction base="xs:string">
&nbsp;&nbsp;&nbsp; <xs:enumeration   value="PRIVATE"/>
&nbsp;&nbsp;&nbsp; <xs:enumeration value="PRIVATE"/>
="BUSINESS"/>
&nbsp; </xs:restriction>
</xs:simpleType>

Fault NoSuchCustomerException

The Exception we defined is generated as a complexType with the defined details and a message for the fault. It is important here that the Element and the Message have different names. We ensure this by using the @Webfault Annotation above. Else the later Java Code generation will produce an ugly Exception name NoSuchCustomerException_Exception.

Code Block
xml
xml

<xs:element name="NoSuchCustomer" type="tns:NoSuchCustomer"/>
    <xs:complexType name="NoSuchCustomer">
        <xs:sequence>
            <xs:enumeration value="BUSINESSelement name="customerName" nillable="true" type="xs:string"/>
        </xs:restriction>sequence>
 </xs:simpleType>:complexType>
 <wsdl:message name="NoSuchCustomerException">
    <wsdl:part name="NoSuchCustomerException" element="tns:NoSuchCustomer">
    </wsdl:part>
  </wsdl:message>

The wsdl defines a SOAP/HTTP binding by default but can also be used to build services based on JMS as I will show in my next post.

...

In the next post I will show ho to build service consumers and providers using the WSDL we just built.

You can download the complete example here.

References