Webcast on .NET client + AXIS service

Simon has put together a set of webcasts covering webservices interop. One of them covered a .NET client connecting to an AXIS server. I hadn't viewed it until now. 

The approach he takes in the webcast is to

  1. define a schema with the various message types
  2. use Exolab's Castor to generate Java types from the XSD
  3. hand-author a service, as well as an AXIS deployment descriptor, and its undeploy.wsdd cousin.
  4. compile and deploy to Tomcat

I generally don't follow this approach. I like the idea of designing the message schema up front, as W3C XML Schema. Castor is as good as any other Java-to-XML binding framework. In fact, AXIS has its own. So the simplest example wouldn't use Castor + AXIS.  

Hand-authoring the service, as well as the deployment descriptors, seems like a lot to ask. 

What I normally do, and what I recommend, is to go WSDL first. Create the schema, any way you want. Then define the WSDL, and reference the schema. 

"But Hey," you're thinking, "hand-authoring WSDL is just as onerous as hand-authoring the AXIS service and the deployment descriptors." You're right. In fact, it's worse! But you don't need to hand-author it. 

The approach I recommend is to start with a WSDL template, and drop-in references to the app-specific schema you've defined. Then use the AXIS WSDL2Java tool (like the wsdl.exe tool for .NET) to generate the server-side stubs, data type classes, and skeleton implementation. The AXIS tool will even generate the deploy.wsdd file for you. 

To get the WSDL template, you can use an AXIS JWS file, or start by writing a Java service and exposing it within AXIS and then auto-generating the WSDL with the ?wsdl URL request. I always start with the same simple WSDL template, and then using a text editor, add in the schema reference, and insert the operation names and so on. I got the template from Yasser's MSDN article from December 2002. In particular, see the source code, Figure 5.

Here's my WSDL template.

    1 <!--

    2     1. Change targetNamespace, tns and s0 namespace.

    3        It's easiest but not required if you set this

    4        targetNamespace to the same value you used for

    5        the schema targetNamespace. Include other namespace

    6        prefix definitions here, as necessary.

    7 -->

    8 <definitions

    9     xmlns="https://schemas.xmlsoap.org/wsdl/"

   10     targetNamespace="urn:The-WSDL-target-namespace"

   11     xmlns:tns="urn:The-WSDL-target-namespace"

   12     xmlns:s0="urn:The-Schema-namespace"

   13     xmlns:soap="https://schemas.xmlsoap.org/wsdl/soap/">

   14 

   15     <!--

   16         2. import your schema. Update the namespace to agree

   17            with s0 above. Import other schema as well.

   18            Remember, the location is just a hint!

   19         -->

   20 

   21         <import

   22         namespace="urn:The-Schema-namespace"

   23         location="URL to your schema" />

   24 

   25     <types/>

   26 

   27     <!--

   28         3. Change message names if you want to.

   29            If you do, be sure to change the corresponding message

   30            names inside the operations. (step 7 below)

   31         4. Change part names and element names. Element names must

   32            correspond to elements declared in your schema. If you want

   33            more than one operation, add pairs of messages.

   34     -->

   35 <message name="RequestMessage">

   36    <part name="inPart1" element="s0:some element in schema" />

   37 </message>

   38 <message name="ResponseMessage">

   39    <part name="outPart1" element="s0:some element in schema" />

   40 </message>

   41 

   42     <!--

   43         5. Change the port type name if you want to.

   44         6. Change the operation name. This becomes the

   45             Webmethod's name. Add more operations, as needed.

   46         7. Change the message names here if you changed the

   47             message names above.

   48     -->

   49 

   50 <portType name="PortTypeName">

   51   <operation name="OperationName">

   52       <input message="s0:RequestMessage" />

   53       <output message="s0:ResponseMessage" />

   54    </operation>   

   55 </portType>

   56 

   57 <!--

   58     8. Change the binding name. This

   59        becomes the name of the interface in your code.

   60     9. Change the value of the type attribute

   61        to match the port type name you used above.

   62     10. Change the operation name to match the above. (step 6)

   63 -->

   64 

   65 <binding name="Interface1" type="s0:PortTypeName">

   66     <soap:binding

   67        transport="https://schemas.xmlsoap.org/soap/http"

   68        style="document" />

   69     <operation name="OperationName">

   70         <soap:operation soapAction="" style="document" />

   71         <input>

   72             <soap:body use="literal" />

   73         </input>

   74         <output>

   75             <soap:body use="literal" />

   76         </output>

   77     </operation>

   78 </binding>

   79 

   80 <!--

   81   These steps are needed only if you use this WSDL

   82     to generate server-side implementation skeletons.

   83 

   84     11. Reference the binding you defined in #8 above.

   85     12. change the service name. This becomes the name

   86         of the service in the web services container.

   87     13. change the module name. This becomes the name of generated

   88         code module. 

   89     -->

   90 

   91    <wsdl:service name="Module1">

   92       <wsdl:port binding="tns:Interface1" name="MyService">

   93         <wsdlsoap:address location="https://unknown.location" />

   94       </wsdl:port>

   95    </wsdl:service>

   96 

   97 </definitions>

Anyone know of a WSDL mode for emacs?