Difference between revisions of "Access an external web service using SOAP"

From AgileApps Support Wiki
imported>Aeric
imported>Aeric
 
(14 intermediate revisions by the same user not shown)
Line 1: Line 1:
This sample shows how to make a {{^SOAP}} request to an external service.
This sample shows how to make a {{^SOAP}} request to an external service. It is based on a working example, but it has been simplified to make it easier to follow. It therefore will not work "as is". Use it as a template to guide your own developments.
 
It is based on a working example, but it has been simplified so it is (somewhat) easier to follow. It therefore will not work "as is". Use it as a template to guide your own developments.
__TOC__
__TOC__
===Sample WSDL===
===Sample WSDL===
Line 68: Line 66:


===Sample Code===
===Sample Code===
Here is the code that accesses the remote service. The WSDL definition was used to format the SOAP request and to determine the response format.  
Here is the code that accesses the remote service. The WSDL definition was used to format the SOAP request and to determine the response format. To use this code, you would place it into a <tt>Calculator</tt> class. You could then invoke the <tt>add()</tt> method it defines from a Rule or from other platform code.
 
:<syntaxhighlight lang="java" enclose="div">
To use this code, you would place it into a <tt>Calculator</tt> class, and invoke the <tt>add()</tt> method from a Rule or from other platform code.
:<syntaxhighlight lang="xml" enclose="div">
// These libraries are part of the platform.  
// These libraries are part of the platform.  
// Import them here to make them available to the class.
// Import them here to make them available to the class.
Line 85: Line 81:
     public void add(Parameters p) throws Exception
     public void add(Parameters p) throws Exception
     {
     {
       // Here the parameters are assumed to be "x" and "y".
       // Here, the record parameters are assumed to be "order_total" and "shipping".
       // When you invoke a method in the platform, it will always be for some record.
       // When you invoke a method in the platform, it will always be for some record.
       // The fields defined for that record are available in the Parameters object.
       // The fields defined for that record are available in the Parameters object.
       // Use lines of code like these to extract them for use in the SOAP request.  
       // Use lines of code like these to extract them for use in the SOAP request.  
       String x = (String)p.get("x");
       String order_amount = (String)p.get("order_total");
       String y = (String)p.get("y");
       String shipping_cost = (String)p.get("shipping");
        
        
      // The WSDL describes the format of the SOAP request. Here, the extracted
      // params are converted to variables "x" and "y" the expected format.
       String soapRequest =
       String soapRequest =
         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+
         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" xmlns:y=\"http://mydomain.com/calculator/\" xmlns:ns=\"http://mydomain.com/calculator/types/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"+
    "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" xmlns:y=\"http://mydomain.com/calculator/\" xmlns:ns=\"http://mydomain.com/calculator/types/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"+
"  <SOAP-ENV:Body>"+
        "  <SOAP-ENV:Body>"+
"      <mns1:Add xmlns:mns1=\"http://mydomain.com/calculator/\">"+
    "      <mns1:Add xmlns:mns1=\"http://mydomain.com/calculator/\">"+
"        <x>" + x + "</x>"+
    "        <x>" + order_amount  + "</x>"+
"        <y>" + y + "</y>"+
    "        <y>" + shipping_cost + "</y>"+
"      </mns1:Add>"+
    "      </mns1:Add>"+
"  </SOAP-ENV:Body>"+
    "  </SOAP-ENV:Body>"+
"</SOAP-ENV:Envelope>";
    "</SOAP-ENV:Envelope>";
        
        
       // Create an HTTP connection to use for the SOAP request,
       // Create an HTTP connection to use for the SOAP request,
Line 120: Line 118:
       Sample Response, as determined by the WSDL
       Sample Response, as determined by the WSDL
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
    <?xml version=\"1.0\" encoding=\"UTF-8\"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" xmlns:y=\"http://mydomain.com/calculator/\" xmlns:ns=\"http://mydomain.com/calculator/types/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"+
    <SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" xmlns:y=\"http://mydomain.com/calculator/\" xmlns:ns=\"http://mydomain.com/calculator/types/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"+
  <SOAP-ENV:Body>"+
      <SOAP-ENV:Body>"+
      <mns1:AddResponse xmlns:mns1=\"http://mydomain.com/calculator/\">
          <mns1:AddResponse xmlns:mns1=\"http://mydomain.com/calculator/\">
        <result>1</result>
            <result>2</result>
      </mns1:AddResponse>
          </mns1:AddResponse>
  </SOAP-ENV:Body>
      </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
    </SOAP-ENV:Envelope>
       ********************************************/
       ********************************************/
   
   
       //Extract the result element from the response:
       // Extract the result element from the response:
       // 1. Convert XML response to JSON using the org.json package
       // 1. Convert XML response to JSON using the org.json package
       // 2. Extract the result element from the JSON structure
       // 2. Extract the result element from the JSON structure
       JSONObject jo = org.json.XML.toJSONObject(response);      
       JSONObject jo = org.json.XML.toJSONObject(response);      
       String resultElement = jo.getJSONObject("SOAP-ENV:Envelope")
       String resultElement = jo.getJSONObject("SOAP-ENV:Envelope")
.getJSONObject("SOAP-ENV:Body")
                .getJSONObject("SOAP-ENV:Body")
      .getJSONObject("mns1:AddResponse")
                    .getJSONObject("mns1:AddResponse")
      .getString("result");
                    .getString("result");
     }
}
      // The data returned from the SOAP request can be used here. For
      // example, the Java API could be used to update the current record
      // with the retrieved value.
        ...
 
     } // add() method
} // Calculator class
</syntaxhighlight>
</syntaxhighlight>


=== Learn More ===
=== Learn More ===
:* [{{DOCHOST}}/javadocs/com/platform/api/HttpConnection.html HttpConnection class]
:* [{{DOCHOST}}/javadocs/com/platform/api/HttpConnection.html HttpConnection class]
:* [[Java API]]
:* [[HowTo:Use the HttpConnection Class to access a web service]]

Latest revision as of 01:01, 3 July 2013

This sample shows how to make a SOAP request to an external service. It is based on a working example, but it has been simplified to make it easier to follow. It therefore will not work "as is". Use it as a template to guide your own developments.

Sample WSDL

Here is the sample WSDL (Web Service Description Language) the code is based on:

<syntaxhighlight lang="xml" enclose="div">

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"

 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
 xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
 xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" 
 xmlns:y="http://mydomain.com/calculator/" 
 xmlns:ns="http://mydomain.com/calculator/types/" 
 targetNamespace="http://mydomain.com/calculator/">
  <types>
    <xs:schema targetNamespace="http://mydomain.com/calculator/types/" 
      xmlns="http://mydomain.com/calculator/types/" 
      elementFormDefault="unqualified" attributeFormDefault="unqualified">
        <xs:complexType name="CalculatorInput">
           <xs:sequence>
              <xs:element name="x" type="xs:double"/>
              <xs:element name="y" type="xs:double"/>
           </xs:sequence>
        </xs:complexType>
        <xs:complexType name="CalculatorOutput">
           <xs:sequence>
              <xs:element name="result" type="xs:double"/>
           </xs:sequence>
        </xs:complexType>
        <xs:element name="Add" type="CalculatorInput"/>
        <xs:element name="AddResponse" type="CalculatorOutput"/>
     </xs:schema>
  </types>
  <message name="AddMessage">
     <part name="parameters" element="ns:Add"/>
  </message>
  <message name="AddResponseMessage">
     <part name="parameters" element="ns:AddResponse"/>
  </message>
  <portType name="CalculatorInterface">
     <operation name="Add">
        <input message="y:AddMessage"/>
        <output message="y:AddResponseMessage"/>
     </operation>
  </portType>
  <binding name="CalculatorSoapHttpBinding" type="y:CalculatorInterface">
     <soap:binding style="document" 
        transport="http://schemas.xmlsoap.org/soap/http"/>
     <operation name="Add">
        <soap:operation soapAction="http://mydomain.com/calculator/#Add"/>
        <input>
           <soap:body use="literal"/>
        </input>
        <output>
           <soap:body use="literal"/>
        </output>
     </operation>
  </binding>
  <service name="CalculatorService">
     <port name="CalculatorEndpoint" binding="y:CalculatorSoapHttpBinding">
        <soap:address location="http://mydomain.com/Calculator/Calculator.asmx"/>
     </port>
  </service>

</definitions> </syntaxhighlight>

Sample Code

Here is the code that accesses the remote service. The WSDL definition was used to format the SOAP request and to determine the response format. To use this code, you would place it into a Calculator class. You could then invoke the add() method it defines from a Rule or from other platform code.

<syntaxhighlight lang="java" enclose="div">

// These libraries are part of the platform. // Import them here to make them available to the class. import com.platform.api.*; import org.json.*; import java.util.Map; import java.util.HashMap; import java.util.Iterator;

public class Calculator {

   // This method makes a request to an external web service to add two values.
   public void add(Parameters p) throws Exception
   {
     // Here, the record parameters are assumed to be "order_total" and "shipping".
     // When you invoke a method in the platform, it will always be for some record.
     // The fields defined for that record are available in the Parameters object.
     // Use lines of code like these to extract them for use in the SOAP request. 
     String order_amount = (String)p.get("order_total");
     String shipping_cost = (String)p.get("shipping");
     
     // The WSDL describes the format of the SOAP request. Here, the extracted
     // params are converted to variables "x" and "y" the expected format.
     String soapRequest =
       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+
   "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" xmlns:y=\"http://mydomain.com/calculator/\" xmlns:ns=\"http://mydomain.com/calculator/types/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"+
       "   <SOAP-ENV:Body>"+
   "      <mns1:Add xmlns:mns1=\"http://mydomain.com/calculator/\">"+
   "         <x>" + order_amount  + "</x>"+
   "         <y>" + shipping_cost + "</y>"+
   "      </mns1:Add>"+
   "   </SOAP-ENV:Body>"+
   "</SOAP-ENV:Envelope>";
     
     // Create an HTTP connection to use for the SOAP request,
     // using the built-in HttpConnection class
     HttpConnection con = new HttpConnection(
         CONSTANTS.HTTP.METHOD.POST,
         "http://mydomain.com/Calculator/Calculator.asmx");
     
     con.addHeader("SOAPAction","http://mydomain.com/calculator/#Add");      
     con.addHeader("Content-Type","text/xml");
     con.setRequestBody(soapRequest);
     
     // Send the request and get the response
     int code = con.execute();
     String response = con.getResponse();
     /*******************************************
      Sample Response, as determined by the WSDL
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
   <?xml version=\"1.0\" encoding=\"UTF-8\"?>
   <SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" xmlns:y=\"http://mydomain.com/calculator/\" xmlns:ns=\"http://mydomain.com/calculator/types/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"+
      <SOAP-ENV:Body>"+
         <mns1:AddResponse xmlns:mns1=\"http://mydomain.com/calculator/\">
            <result>2</result>
         </mns1:AddResponse>
      </SOAP-ENV:Body>
   </SOAP-ENV:Envelope>
     ********************************************/

     // Extract the result element from the response:
     //  1. Convert XML response to JSON using the org.json package
     //  2. Extract the result element from the JSON structure
     JSONObject jo = org.json.XML.toJSONObject(response);        
     String resultElement = jo.getJSONObject("SOAP-ENV:Envelope")
               .getJSONObject("SOAP-ENV:Body")
                   .getJSONObject("mns1:AddResponse")
                   .getString("result");

     // The data returned from the SOAP request can be used here. For
     // example, the Java API could be used to update the current record 
     // with the retrieved value.
        ...
   } // add() method

} // Calculator class </syntaxhighlight>

Learn More