Thursday, April 3, 2008

SOAP attachments with AXIS

I wanted to create a Web Service that accepts a JPEG image as the input. The preferred way to send an image in a SOAP message is using SOAP attachments.

Below is a sample WSDL file for a service that accepts an image as input.


<?xml version="1.0" encoding="UTF-8"?>
<definitions name="newWSDL" targetNamespace="http://www.example.com/example"
            xmlns="http://schemas.xmlsoap.org/wsdl/"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:tns="http://www.example.com/example"
            xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/"
            xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/">
  

   <message name="isLabelAuthenticRequest">
       <part name="labelImage" type="xsd:hexBinary"/>
   </message>
   <message name="isLabelAuthenticReply">
       <part name="isAuthentic" type="xsd:boolean"/>
   </message>
  
   <portType name="isLabelAuthenticPortType">
       <operation name="isLabelAuthenticOperation">
           <input name="authenticInput" message="tns:isLabelAuthenticRequest"/>
           <output name="authenticOutput"
 message="tns:isLabelRegisteredOperationReply"/>
       </operation>
   </portType>
  
   <binding name="isLabelAuthenticBinding" type="tns:isLabelAuthenticPortType">
       <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
       <operation name="isLabelAuthenticOperation">
           <soap:operation/>
           <input name="authenticInput">
               <mime:multipartRelated>
                   <mime:part>
                       <soap:body use="encoded"    
   encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://www.example.com/example"/>
                   </mime:part>
                   <mime:part>
                       <mime:content part="labelImage" type="image/jpeg"/>
                   </mime:part>
               </mime:multipartRelated>
           </input>
           <output name="authenticOutput">
               <soap:body use="encoded"
  encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://www.example.com/example"/>
           </output>
       </operation>
   </binding>
  
   <service name="smartLabelDemoService">
       <port name="isLabelAuthenticPort" binding="tns:isLabelAuthenticBinding">
           <soap:address location="http://192.168.0.156:8080/Example/authentic"/>
       </port>
   </service>
  
</definitions>

The highlights of the WSDL file:

  • The following namespace for SOAP must be used to enable support for attachments:
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/
  • The message that will include an attachment is declared to be of type xsd:hexBinary
  • The actual structure of this message is specified in the binding element. It is specified as a multipart message, with the MIME type of the second part set to image/jpeg.

The WSDL2Java utility offered by Axis, should be able to parse this wsdl document and generate the stubs successfully. (I have been using version 1.4 of Axis). Of course, for WSDL2Java to work, all the axis-related jars (ie all the jars in the folder $AXIS_HOME/lib) must be present in the CLASSPATH. Furthermore, for attachment support, we also need mail.jar and activation.jar. The first one is part of the Java Mail API and the second on can be found in the JavaBeans Activation Framework.

However I was getting the following error message when I tried to implement and test the web service:

http://xml.apache.org/axis/}stackTrace:org.xml.sax.SAXException: Bad envelope tag:  html
  org.apache.axis.message.EnvelopeBuilder.startElement(EnvelopeBuilder.java:71)
  ...

I could only understand what was causing this when I used the tcpmon utility to monitor the TCP connections. This actually revealed that the server was returning an HTML document (rather than a SOAP message) containing an error message:

java.lang.RuntimeException: No support for attachments
  org.apache.axis.Message.setup(Message.java:372)
  ...

So, it was a matter of just enabling attachment support on the server side. This can be done by simply copying mail.jar and activation.jar under the location where axis has been deployed, ie under the directory $CATALINA_HOME/webapps/axis/lib.

No comments: