Monday, August 8, 2011

Creating MTOM Enabled JAX-WS Web Services Using RAD/WID/Integration Designer

Summary:
Learn how to develop MTOM enabled JAX-WS web services using Rational Application Developer (RAD) or WebSphere Integration Developer (WID) or IBM Integration Designer. A detailed development process for both Top-Down and Bottom-Up approaches is presented.


MTOM (Message Transmission Optimization Mechanism) is a W3C standard that uses XOP (XML Binary Optimized Packaging) to transmit binary data. For more information on MTOM or XOP, please refer to [1] and [2] in the references section.

Scenario: Create a web service using Java API for XML-Based Web Services (JAX-WS) with an operation called “getFileAsMTOM” that will accept a file name as input and will return a response message with the file content as attachment using MTOM/XOP. The operation will also return the file name provided in the input, as part of the output. The implementation of the operation could include logic to read the file in a particular folder on the local drive and return it as part of the response.

A detailed development process for both Top-Down and Bottom-Up approaches is presented.

Bottom-Up Approach

There are two different service endpoint implementation types that you could use to develop web services using JAX-WS. (Refer to [4] in the References section for more information.)
  1. JavaBeans Service Endpoint Interface and
  2. Provider Interface
This article follows the first method to creating the web service using the Bottom-Up approach.

Steps:

  • Create the Request JavaBean  ( SampleRequest.java - input object for the operation to be exposed on the web service interface). 
Input POJO - SampleRequest.java

  • Create the Response JavaBean (output object for the operation to be exposed on the web service interface).
Output POJO - SampleResponse.java

  • Create the Service Endpoint Interface.
TestMTOMIntf.java - Interface (SEI)

  • Create the Implementation class that implements the Service Endpoint Interface.
TestMTOM.java - Implementation Class

  • Add JAX-WS annotations as necessary. On both S.E.Interface and the Implementation classes add the annotations as necessary. In the above pictures named "TestMTOMIntf.java - Interface (SEI)" and "TestMTOM.java - Implementation Class", find the annotations that were added for this example. Refer to [3] in the References section for more information on JAX-WS annotations.

  • Add                                                                                                                "@javax.xml.ws.BindingType (value=javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING)"  or              "@javax.xml.ws.BindingType (value=javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING)" based on whether you are using SOAP 1.1 or SOAP 1.2 binding. Add the annotation on the Implementation class to enable MTOM as shown above in the picture named "TestMTOM.java - Implementation Class".

  • Generate the necessary artifacts.
Generate WSDL and Other artifacts

Generate Artifacts 2 (select JAX-WS)


Generate Artifacts 3 ("Enable MTOM Support" should show selected)


BottomUp - Web Project Showing Generated Artifacts

  • Deploy to WAS/WESB/WPS and Test. In this example i used soapUI to test the operation. You can see in the picture that <xop:Include> tag has been added and you can see an attachment. From the soapUI tool, you can download the attachment, name the file appropriate and view the same to make sure you got back what you were expecting.
soapUI - TestCase - BottomUp

Top-Down Approach

In the Top-Down approach, we start with creating a WSDL file. We then generate the necessary Java Beans and then code the logic in the generated implementation class.

Steps:
  • Create the WSDL file.
                                                    MTOMInterface.WSDL


<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions name="MTOMInterface" targetNamespace="http://Sample/MTOMInterface" xmlns:bons1="http://Sample" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://Sample/MTOMInterface" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:types>
    <xsd:schema targetNamespace="http://Sample/MTOMInterface">
      <xsd:import namespace="http://Sample"/>
      <xsd:element name="getFileAsMTOM">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="input1" nillable="true" type="bons1:SampleRequest"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="getFileAsMTOMResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="output1" nillable="true" type="bons1:SampleResponse"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
        <xsd:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://Sample">
      <xsd:complexType name="SampleResponse">
  <xsd:sequence>
   <xsd:element minOccurs="0" name="FileContent" type="xsd:base64Binary">
   </xsd:element>
   <xsd:element minOccurs="0" name="FileName" type="xsd:string">
   </xsd:element>
  </xsd:sequence>
 </xsd:complexType>
      <xsd:complexType name="SampleRequest">
  <xsd:sequence>
   <xsd:element minOccurs="0" name="FileName" type="xsd:string">
   </xsd:element>
  </xsd:sequence>
 </xsd:complexType>
    </xsd:schema>
    </wsdl:types>
    <wsdl:message name="getFileAsMTOMRequestMsg">
    <wsdl:part element="tns:getFileAsMTOM" name="getFileAsMTOMParameters"/>
  </wsdl:message>
    <wsdl:message name="getFileAsMTOMResponseMsg">
    <wsdl:part element="tns:getFileAsMTOMResponse" name="getFileAsMTOMResult"/>
  </wsdl:message>
    <wsdl:portType name="MTOMInterface">
    <wsdl:operation name="getFileAsMTOM">
      <wsdl:input message="tns:getFileAsMTOMRequestMsg" name="getFileAsMTOMRequest"/>
      <wsdl:output message="tns:getFileAsMTOMResponseMsg" name="getFileAsMTOMResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  
  <wsdl:binding name="MTOMInterfaceHttpBinding" type="tns:MTOMInterface">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getFileAsMTOM">
      <soap:operation soapAction=""/>
      <wsdl:input name="getFileAsMTOMRequest">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getFileAsMTOMResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="FetchFileService">
    <wsdl:port binding="tns:MTOMInterfaceHttpBinding" name="MTOMInterfaceHttpPort">
      <soap:address location="http://localhost:9080/TEST/FetchFileService"/>
    </wsdl:port>
  </wsdl:service> 
</wsdl:definitions>

  • Generate the JavaBean Skeleton by enabling MTOM support.
Generate Java Bean Skeleton - TopDown

Generate Java Bean Skeleton (select JAX-WS) - TopDown

Generate Java Bean Skeleton (Enable MTOM) - TopDown
  • Implement the logic for the operation that is to be exposed.
MTOMInterfaceHttpBindingImpl - Implementation Class

MTOMInterfaceHttpBindingImpl - Implementation Class
  • Deploy to WAS/WESB/WPS and Test. In this example i used soapUI to test the operation. You can see in the picture that <xop:Include> tag has been added and you can see an attachment. From the soapUI tool, you can download the attachment, name the file appropriate and view the same to make sure you got back what you were expecting.
soapUI - Test MTOM - Top Down

For information on how to enable MTOM on Web Services in DataPower, Please Check my post – DataPower: Encoding base64Binary Inline Data into MTOM.

References:





4 comments:

  1. Hi Hema,

    This was helpful to me. I am now able to get response even if the binary data is several MBs. But after a certian limit( which is better than the limit when MOTOM was not used ) I am getting errors at the client side. Do I need to go for streaming? If yes, can you give me the example?

    Thanks,
    Olive

    ReplyDelete
  2. Using web services for transferring large amounts of data might not be a good idea. However if you are interested in trying out streaming with MTOM, you could probably use JAX-WS RI to do that. Here is some info that might interest you
    1. Metro – Large Attachments
    2. Oracle – Streaming SOAP Attachments(refer "Streaming SOAP Attachments" section)
    3. Metro and WebSphere

    ReplyDelete
  3. MTOM is ideal for service which serves large chunk of binary data. See a good article below
    http://java.globinch.com/enterprise-java/web-services/jax-ws/jax-ws-attachment-enable-mtom-jax-ws-web-services/

    ReplyDelete
  4. Thanks for taking the time to discuss this, I feel strongly about it and love learning more on this topic. If possible, as you gain expertise, would you mind updating your blog with extra information? It is extremely helpful for me. peter web designer

    ReplyDelete