cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject [CONF] Apache CXF Documentation > Defining Contract first webservices with wsdl generation from java
Date Tue, 22 Sep 2009 18:10:00 GMT
    <base href="">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=CXF20DOC&amp;forWysiwyg=true"
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="">Defining
Contract first webservices with wsdl generation from java</a></h2>
     <h4>Page <b>edited</b> by             <a href="">Daniel
     <div class="notificationGreySide">
         <p>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.<br/>
<a href=""
rel="nofollow">The original post is from Christian SchneiderĀ“s blog and can be found here</a></p>

<h2><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-Whatwewouldliketohave"></a>What
we would like to have</h2>

<p>Ideally I would imagine to have a domain specific language that makes designing the
webservice very easy and fail safe. Then there should be an IDE that supports me in writing
the DSL. Either with content assist or with a graphical editor. In any case the IDE should
check the DSL while it is entered and help me to do the right thing. Some people favor using
Model Driven Design tools to do this job but it is quite hard finding good tools and configuring
them for the job.</p>

<h2><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-WhichtoolsdidIchooseandwhy"></a>Which
tools did I choose and why</h2>

<p>I wanted to go some way in the direction of a DSL for webservices but without using
a big MDD tool. So I thought about how to have most advantages of a DSL with just Java and
the normal Eclipse IDE. So I needed Java code that looks almost like a DSL and a tool to generate
the webservice out of it. For the WSDl generation I used Apache CXF with JAXWS and JAXB annotations
to describe the webservice. While this setup is quite standard I focused on keeping the syntax
as simple as possible.</p>

<h2><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-SohowdoestheDSLlooklike"></a>So
how does the DSL look like</h2>

<p>To describe a data object I use a java class with just attributes. The Namespace
will come from the package name. To make JAXB understand this syntax only one annotation is
necessary. Of course some more annotations are necessary if you want to use special fetaures.</p>

<h3><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-Customerdatatype"></a>Customer

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> com.example.customerservice;

@XmlAccessorType( XmlAccessType.FIELD )
<span class="code-keyword">public</span> class Customer {
    <span class="code-object">String</span> name;
    <span class="code-object">String</span>\[\] address;
    <span class="code-object">int</span> numOrders;
    <span class="code-object">double</span> revenue;
    BigDecimal test;
    Date birthDate;
    CustomerType type;
<p>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.</p>

<h3><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-EnumerationCustomerType"></a>Enumeration

<p>Shows how enumerations are handled:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> com.example.customerservice;

<span class="code-keyword">public</span> <span class="code-keyword">enum</span>
CustomerType {

<h3><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-NoSuchCustomerException"></a>NoSuchCustomerException</h3>

<p>&nbsp;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.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> com.example.customerservice;

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

<h3><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-Servicedefinition"></a>Service

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> com.example.customerservice;

<span class="code-keyword">public</span> <span class="code-keyword">interface</span>
CustomerService {
<span class="code-keyword">public</span> Customer[] getCustomersByName(@WebParam(name=<span
class="code-quote">"name"</span>) <span class="code-object">String</span>
name) <span class="code-keyword">throws</span> NoSuchCustomerException;
<p>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.</p>

<h2><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-Howisthewsdlgenerated"></a>How
is the wsdl generated</h2>

<p>To generate the wsdl the maven plugin cxf-java2ws-plugin is used. See the pom.xml
in the complete example for details.
<br clear="all" /></p>

<h2><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-Let%C2%B4stakealookattheresultingWSDL"></a>LetĀ“s
take a look at the resulting WSDL</h2>

<p>You can <a href="/confluence/download/attachments/93162/CustomerService.wsdl?version=2">download
the wsdl this example creates here</a>.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;xs:complexType name=<span class="code-quote">"customer"</span>&gt;</span>
    <span class="code-tag">&lt;xs:sequence&gt;</span>
        <span class="code-tag">&lt;xs:element minOccurs=<span class="code-quote">"0"</span>
name=<span class="code-quote">"name"</span> type=<span class="code-quote">"xs:string"</span>/&gt;</span>
        <span class="code-tag">&lt;xs:element maxOccurs=<span class="code-quote">"unbounded"</span>
minOccurs=<span class="code-quote">"0"</span> name=<span class="code-quote">"address"</span>
nillable=<span class="code-quote">"true"</span> type=<span class="code-quote">"xs:string"</span>/&gt;</span>
        <span class="code-tag">&lt;xs:element name=<span class="code-quote">"numOrders"</span>
type=<span class="code-quote">"xs:int"</span>/&gt;</span>
        <span class="code-tag">&lt;xs:element name=<span class="code-quote">"revenue"</span>
type=<span class="code-quote">"xs:double"</span>/&gt;</span>
        <span class="code-tag">&lt;xs:element minOccurs=<span class="code-quote">"0"</span>
name=<span class="code-quote">"test"</span> type=<span class="code-quote">"xs:decimal"</span>/&gt;</span>
        <span class="code-tag">&lt;xs:element minOccurs=<span class="code-quote">"0"</span>
name=<span class="code-quote">"birthDate"</span> type=<span class="code-quote">"xs:dateTime"</span>/&gt;</span>
        <span class="code-tag">&lt;xs:element minOccurs=<span class="code-quote">"0"</span>
name=<span class="code-quote">"type"</span> type=<span class="code-quote">"tns:customerType"</span>/&gt;</span>
    <span class="code-tag">&lt;/xs:sequence&gt;</span>
<span class="code-tag">&lt;/xs:complexType&gt;</span>
<p>The customer Class is a complex type in xsd. As you can see the Java types have been
described as their respective XSD primitive types.</p>

<p>Each element has minOccurs="0" which marks it as optional. This is a good thing as
you can add new optional elements and keep compatible. If you do not want this optionality
you can use @XmlElement(required=true).</p>

<p>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.</p>

<h3><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-EnumerationcustomerType"></a>Enumeration

<p>The enumeration customerType is described as a simple type with a restriction:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;xs:simpleType name=<span class="code-quote">"customerType"</span>&gt;</span>
    <span class="code-tag">&lt;xs:restriction base=<span class="code-quote">"xs:string"</span>&gt;</span>
        <span class="code-tag">&lt;xs:enumeration value=<span class="code-quote">"PRIVATE"</span>/&gt;</span>
        <span class="code-tag">&lt;xs:enumeration value=<span class="code-quote">"BUSINESS"</span>/&gt;</span>
    <span class="code-tag">&lt;/xs:restriction&gt;</span>
<span class="code-tag">&lt;/xs:simpleType&gt;</span>

<h3><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-FaultNoSuchCustomerException"></a>Fault

<p>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.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;xs:element name=<span class="code-quote">"NoSuchCustomer"</span>
type=<span class="code-quote">"tns:NoSuchCustomer"</span>/&gt;</span>
    <span class="code-tag">&lt;xs:complexType name=<span class="code-quote">"NoSuchCustomer"</span>&gt;</span>
        <span class="code-tag">&lt;xs:sequence&gt;</span>
            <span class="code-tag">&lt;xs:element name=<span class="code-quote">"customerName"</span>
nillable=<span class="code-quote">"true"</span> type=<span class="code-quote">"xs:string"</span>/&gt;</span>
        <span class="code-tag">&lt;/xs:sequence&gt;</span>
 <span class="code-tag">&lt;/xs:complexType&gt;</span>
 <span class="code-tag">&lt;wsdl:message name=<span class="code-quote">"NoSuchCustomerException"</span>&gt;</span>
    <span class="code-tag">&lt;wsdl:part name=<span class="code-quote">"NoSuchCustomerException"</span>
element=<span class="code-quote">"tns:NoSuchCustomer"</span>&gt;</span>
    <span class="code-tag">&lt;/wsdl:part&gt;</span>
 <span class="code-tag">&lt;/wsdl:message&gt;</span>
<p>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.</p>

<h2><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-Summary"></a>Summary</h2>

<p>As you can see the generated WSDL looks quite clean and correctly expresses the service
interface we wanted to describe. In most cases where you are not satisfied with what the conversion
does you can correct the WSDL using JAX-WS or JAXB annotations. But I recommend to use them
sparsly to keep the DSL easy to read.</p>

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

<p>You can <a href="/confluence/download/attachments/93162/">download
the complete example here</a>.
<br clear="all" /></p>

<h2><a name="DefiningContractfirstwebserviceswithwsdlgenerationfromjava-References"></a>References</h2>

	<li><a href="" rel="nofollow">Apache CXF</a></li>
	<li><a href=""
rel="nofollow">This Article in the CXF Documentation</a></li>
	<li><a href="" rel="nofollow">JAX-WS specification</a>&nbsp;</li>
	<li><a href=""
rel="nofollow">JAXB Architecture</a></li>
	<li><a href="" rel="nofollow">JAXB user guide</a></li>
	<li><a href=""
rel="nofollow">JAXB Tutorial</a>
<br clear="all" /></li>

     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href=""
class="grey">Change Notification Preferences</a>

       <a href="">View
       <a href="">View
       <a href=";showCommentArea=true#addcomment">Add

View raw message