Skip to Content
Author's profile photo Former Member

Consuming WebServices directly from ABAP

A time ago I was asked to create a Webservice consumption directly from ABAP without any soa.

We listen too much about SAP PI as an integrator and every SAP connection is done thru it (that’s the best way to do it, I think) but it is not the only way. Since ERP 4.7  it is possible to consume/provide services directly from ABAP.

When our scenario is SAP -> WebService the first thing we need is a working webservice.

Test service:

Here I’ll create a Service Consumer for consumption of a test webservice from http://www.webservicex.net/length.asmx?WSDL it’s service that converts lenght units.

First, let’s take a better look to the WSDL:

In this file there are 3 operations:

  • lengthUnitSoap
  • lengthUnitHttpGet
  • lengthUnitHttpPost

For this post the only relevant port service is lengthUnitSoap that implements Soap standards. The two others are for HTTP consumption directly (not our focus here).

Before we can simply import our file to SAP, taking a better look into it we see that some messages have more than one part tag:

/wp-content/uploads/2013/07/1_253510.png

This kind of message is incompatible with SAP, so if there are any messages with more than exactly one part tag the system will return you an error before import your file. Even if the message is not used in the service that you are implementing.

In thes scenario what can we do?

Simple: we can edit the file to match our needs.

Save the original WSDL file to your computer (as .xml or .wsdl) then edit it.

The editted WSDL file shoud seem like this:

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.webserviceX.NET/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://www.webserviceX.NET/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://www.webserviceX.NET/">
      <s:element name="ChangeLengthUnit">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="LengthValue" type="s:double" />
            <s:element minOccurs="1" maxOccurs="1" name="fromLengthUnit" type="tns:Lengths" />
            <s:element minOccurs="1" maxOccurs="1" name="toLengthUnit" type="tns:Lengths" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:simpleType name="Lengths">
        <s:restriction base="s:string">
          <s:enumeration value="Angstroms" />
          <s:enumeration value="Nanometers" />
          <s:enumeration value="Microinch" />
          <s:enumeration value="Microns" />
          <s:enumeration value="Mils" />
          <s:enumeration value="Millimeters" />
          <s:enumeration value="Centimeters" />
          <s:enumeration value="Inches" />
          <s:enumeration value="Links" />
          <s:enumeration value="Spans" />
          <s:enumeration value="Feet" />
          <s:enumeration value="Cubits" />
          <s:enumeration value="Varas" />
          <s:enumeration value="Yards" />
          <s:enumeration value="Meters" />
          <s:enumeration value="Fathoms" />
          <s:enumeration value="Rods" />
          <s:enumeration value="Chains" />
          <s:enumeration value="Furlongs" />
          <s:enumeration value="Cablelengths" />
          <s:enumeration value="Kilometers" />
          <s:enumeration value="Miles" />
          <s:enumeration value="Nauticalmile" />
          <s:enumeration value="League" />
          <s:enumeration value="Nauticalleague" />
        </s:restriction>
      </s:simpleType>
      <s:element name="ChangeLengthUnitResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="ChangeLengthUnitResult" type="s:double" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="double" type="s:double" />
    </s:schema>
  </wsdl:types>
  <wsdl:message name="ChangeLengthUnitSoapIn">
    <wsdl:part name="parameters" element="tns:ChangeLengthUnit" />
  </wsdl:message>
  <wsdl:message name="ChangeLengthUnitSoapOut">
    <wsdl:part name="parameters" element="tns:ChangeLengthUnitResponse" />
  </wsdl:message>
  <wsdl:portType name="lengthUnitSoap">
    <wsdl:operation name="ChangeLengthUnit">
      <wsdl:input message="tns:ChangeLengthUnitSoapIn" />
      <wsdl:output message="tns:ChangeLengthUnitSoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="lengthUnitSoap" type="tns:lengthUnitSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="ChangeLengthUnit">
      <soap:operation soapAction="http://www.webserviceX.NET/ChangeLengthUnit" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="lengthUnitSoap12" type="tns:lengthUnitSoap">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="ChangeLengthUnit">
      <soap12:operation soapAction="http://www.webserviceX.NET/ChangeLengthUnit" style="document" />
      <wsdl:input>
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="lengthUnit">
    <wsdl:port name="lengthUnitSoap" binding="tns:lengthUnitSoap">
      <soap:address location="http://www.webservicex.net/length.asmx" />
    </wsdl:port>
    <wsdl:port name="lengthUnitSoap12" binding="tns:lengthUnitSoap12">
      <soap12:address location="http://www.webservicex.net/length.asmx" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Creating an ABAP Proxy:

After deleting the messages without only one part and the respectively port-types we can import the WSDL file into SAP.

To do so in transaction SE80 select package from the dropdown create or use an existent package to your services and right click it select Create->Enterprise Service:

/wp-content/uploads/2013/07/2_253514.png

A Wizzard will start.

Select Service Consumer an click continue:

/wp-content/uploads/2013/07/3_253515.png

Select Local File and click Continue:

/wp-content/uploads/2013/07/4_253516.png

Select the editted WSDL file and click continue:

/wp-content/uploads/2013/07/5_253520.png

Select Package, Prefix and Request to your Service consumer and click Continue:

/wp-content/uploads/2013/07/6_253521.png

IMPORTANT: The prefix must be started with Z or Y otherwise the SAP will ask for object Keys.

Click Complete:

/wp-content/uploads/2013/07/7_253522.png

Our service consumer is now created, but it is still not activated:

/wp-content/uploads/2013/07/8_253529.png

Click the Activate Button /wp-content/uploads/2013/07/9_253530.png.

Sucssess! /wp-content/uploads/2013/07/10_253531.png

We’re now half way done.

We have our proxy but it still does not works. That’s because we have not configured the endpoint of service.

To do so I’ll go to transaction SOAMANAGER. (LPCONFIG in older versions) where we’ll configure the endpoit of our service.

Configuration:

Go to transaction SOAMANAGER if everything goes right you’ll be redirected to a web browser in the following page (if you were redirected to a login page, just fill your SAP user/password):

/wp-content/uploads/2013/07/11_253532.png

Click in Application and Scenario Communicaton and Single Service Administration:

/wp-content/uploads/2013/07/12_253533.png

Search for your created proxy (just remember it is a Consumer Proxy):

/wp-content/uploads/2013/07/13_253534.png

Tip: you can find both  External and Internal name in tab External View from your proxy:

/wp-content/uploads/2013/07/14_253535.png

Back to our Webservice Administration:

Select your service, click Apply Selection Button and go to Configurations tab:

/wp-content/uploads/2013/07/15_253536.png

Click Create Logical Port Button Fill the port name, Description, Configuration Type and WSDL Base:

(the File with WSDL Document is your modifyed WSDL document that you saved in your computer in the beginning of this post)

/wp-content/uploads/2013/07/16_253537.png

Click Apply Settings and Save:

/wp-content/uploads/2013/07/17_253547.png

Testing:

Back in our SAP ERP system we can test the service just by clicking in test tool (F8).

Select your Logical Port (just created) and click on execute button:

/wp-content/uploads/2013/07/18_253548.png

Fill some valid Values:

/wp-content/uploads/2013/07/19_253549.png

Click on Execute Button  and check the response:

/wp-content/uploads/2013/07/20_253550.png

Calling From ABAP Program:

Here is a test program for calling this Proxy:

*& Report  ZTEST_PROXY
 REPORT  ZTEST_PROXY.
 * Data Declarations
 DATA: cl_proxy TYPE REF TO ZCO_LENGTH_UNIT_SOAP, " Proxy Class
       data_in  TYPE ZCHANGE_LENGTH_UNIT_SOAP_IN, " Proxy Input
       data_out TYPE ZCHANGE_LENGTH_UNIT_SOAP_OUT, " Proxy Output
       fault    TYPE REF TO cx_root. " Generic Fault
 * Instantiate the proxy class providing the Logical port name
 CREATE OBJECT cl_proxy EXPORTING LOGICAL_PORT_NAME = 'DEFAULT_PORT'.
 * Set Fixed Values
 data_in-LENGTH_VALUE = '32'.
 data_in-FROM_LENGTH_UNIT = 'Inches'.
 data_in-TO_LENGTH_UNIT  = 'Millimeters'.
 TRY .
   cl_proxy->CHANGE_LENGTH_UNIT( EXPORTING INPUT = data_in
                                 IMPORTING OUTPUT = data_out ).
 CATCH cx_root INTO fault.
 * Here is the place for error handling
   BREAK-POINT.
 ENDTRY.
 *  Here the structure data_out is filled case none Exceptions occurs
 BREAK-POINT.

Assigned Tags

      5 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Great step by step guide!

      Author's profile photo Virgilio Israel Morales
      Virgilio Israel Morales

      Hi Felipe,

      This post it is awesome.

      Thanks for the information

      Happy end of the year.

      Author's profile photo Fábio Luiz Orlandi
      Fábio Luiz Orlandi

      Hi Felipe,

      I liked your tutorial ...
      I wonder if you can help me with a problem ...

      I am trying to consume a webservice from CLM by SRM .....
      I have two problems right off the bat ....
      The CLM is not supporting my "encoding =" UTF-16 "" if I change the XML to 8 it generates another error ... This is the point ...... I am not understanding which error ...
      CX_XSDANY_PARSE_ERROR: XSLT exception. An error occurred during serialization in the program ST /1SAI/TASED9220E7BD20ED78E61F..An error was encountered in the parsing of an XML fragment.

      Thank you..

       

      Author's profile photo Vanessa Hayakawa
      Vanessa Hayakawa

      Olá Fábio! Você encontrou a solução para este problema?

      Ocorre o mesmo erro quando tento gerar um proxy quem contém um campo do tipo xtring, pois estou tentando enviar um smartforms para o CPI.

      Author's profile photo Shailendra Sharma
      Shailendra Sharma

      Great Guide. It was very helpful.
      Thank you very much.