Skip to Content
Author's profile photo Amol Gupta

An insight into consuming WebServices from SAP UI5.

Introduction : Many times consultants can be in a situation where the preferred UI Technology is SAPUI5 but services are exposed as WebServices rather than an OData model. The below blog will help you understand how you can consume a WebService from SAPUI5 via an XML model and show it in SAPUI5 user interface. Although some code samples are scattered here an there, one has to spend quite some time to make a scenario work. By the end of this blog you will have a fair understanding of the scenario and code to make it work.

Target Audience : Beginners to Experts alike.

Environment : Eclipse (Mars) with SAPUI5 plugins, Google Chrome browser.

Date Created: 4 Jan 16


I used the following publicly exposed WebServices to create a scenario :

http://www.w3schools.com/xml/tempconvert.asmx

http://www.w3schools.com/xml/tempconvert.asmx?WSDL

A convenient online WebService client :

http://wsdlbrowser.com/

You need to have the WSDL and then you can easily generate XML request and response. This is one of many options but it is interesting that with this site you can work without a Web Service client installation.

When dealing with XML in string format you might have issues using double quotes ” as XML also has them and diving your XML into multiple line. The problem can be resolved by using single quotes to represent strings and using string concatenation :

http://www.w3schools.com/js/js_strings.asp

Capture.PNG

Key code that does the job :

http://scn.sap.com/community/developer-center/front-end/blog/2014/07/23/consuming-web-service-in-sapui5

Sample Code (Thanks to Navya Krishna):

var request = “<Your input xml to the webservice>”; // more info in the appendix section

var response = “”;

$.ajax({

     url : “Your webservice wsdl url”,

     type : “POST”,

     data : request,

     dataType : “text”,

     contentType : “text/xml; charset=\”utf-8\””,

     success : function(data, textStatus, jqXHR) {

          response = data;

          console.log(“SUCCESS”);

     },

     error: function(xhr, status)

     {

          console.log(“ERROR”);

     },

     complete: function(xhr,status) {

         console.log(“COMPLETE”); 

     }

});

NOTE:

1). Since the WebService is not on the same machine as the SAPUI5 application it causes a “No ‘Access-Control-Allow-Origin’ header is present on the requested resource.” error

Capture.PNG

It can be resolved by using the inbuilt proxy. For e.g. url : “proxy/http/www.w3schools.com/xml/tempconvert.asmx?WSDL”,  in the above code.


2). For using the mentioned WebService I had to get rid of  </SOAP-ENV:Envelope> and </SOAP-ENV:Body> tags in my response to make the scenario work.

response = response.replace(‘<soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema“>’, ”);

response = response.replace(“<soap:Body>”, “”);                   

response = response.replace(“</soap:Body>”, “”);                  

response = response.replace(“</soap:Envelope>”, “”);


3). Do not forget to add the libraries required for running the scenario in the Bootstrap

data-sap-ui-libs=”sap.m, sap.ui.commons,sap.ui.table”

Sample code that can consumes a WebService Response, converts it into an XML model and displays the data in a Table :

NOTE: The code here does not run in a sequence if written right after Ajax call. Please use the success or complete functions to ensure code runs in a sequence.

var oModel = new sap.ui.model.xml.XMLModel(); 

function uicontrols(){

     oModel.setXML(response);

}

var oTable = new sap.ui.table.Table({

     id: “table1”

});

oTable.addColumn(

     new sap.ui.table.Column({

          label: new sap.ui.commons.Label({text: “Label1”}),       

          template: new sap.ui.commons.TextField().bindProperty(“value”, “Tag1/text()”) 

     })

);

oTable.addColumn(

     new sap.ui.table.Column({

          label: new sap.ui.commons.Label({text: “Label2”}),

          template: new sap.ui.commons.TextField().bindProperty(“value”, “Tag2/text()”)

  })

);

oTable.setModel(oModel);

oTable.bindRows({path: “/the main XML tag under which Tag1 and Tag2 are present/”});

Appendix :

Sample Request XML based on above mentioned public WebService

var request = ‘<?xml version=”1.0″ encoding=”UTF-8″?>’ +

  ‘<SOAP-ENV:Envelope xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:ns1=”http://www.w3schools.com/xml/“>’ +

  ‘<SOAP-ENV:Body>’ +

  ‘<ns1:CelsiusToFahrenheit>’ +

  ‘<ns1:Celsius>10</ns1:Celsius>’ +

  ‘</ns1:CelsiusToFahrenheit>’ +

  ‘</SOAP-ENV:Body>’ +

  ‘</SOAP-ENV:Envelope>’;


Another sample code that simulates consuming a WebService Response, converting it into an XML model and displaying the data in a Table.

(Thanks to Konstantin Anikeev)

https://scn.sap.com/thread/3307300

// start of code

var oModel = new sap.ui.model.xml.XMLModel();

  oModel.setXML(“<?xml version=\”1.0\” encoding=\”UTF-8\”?>”+

  “<config>”+

  “<item date=\”January 2009\”>”+

  “<mode>1</mode>”+

  “<unit>900</unit>”+

  “<current>1</current>”+

  “<interactive>1</interactive>”+

  “</item>”+

  “<item date=\”February 2009\”>”+

  “<mode>2</mode>”+

  “<unit>400</unit>”+

  “<current>2</current>”+

  “<interactive>5</interactive>”+

  “</item>”+

  “<item date=\”December 2009\”>”+

  “<mode>9</mode>”+

  “<unit>5</unit>”+

  “<current>100</current>”+

  “<interactive>3</interactive>”+

  “</item>”+

  “</config>”);

  try{

  alert(“GETXML>>>>:”+oModel.getXML());

  }catch(e){

  alert(e.message);

  }

  oTable.addColumn(

  new sap.ui.table.Column({

  label: new sap.ui.commons.Label({text: “Date”}),

  template: new sap.ui.commons.TextField().bindProperty(“value”, “@date”)  }

  )

  );

  oTable.addColumn(

  new sap.ui.table.Column({

  label: new sap.ui.commons.Label({text: “Mode”}),

  template: new sap.ui.commons.TextField().bindProperty(“value”, “mode/text()”)  }

  )

  );

  oTable.addColumn(

  new sap.ui.table.Column({

  label: new sap.ui.commons.Label({text: “Unit”}),

  template: new sap.ui.commons.TextField().bindProperty(“value”, “unit/text()”)  }

  )

  );

  oTable.addColumn(

  new sap.ui.table.Column({

  label: new sap.ui.commons.Label({text: “Current”}),

  template: new sap.ui.commons.TextField().bindProperty(“value”, “current/text()”)  }

  )

  );

  oTable.addColumn(

  new sap.ui.table.Column({

  label: new sap.ui.commons.Label({text: “Interactive”}),

  template: new sap.ui.commons.TextField().bindProperty(“value”, “interactive/text()”)  }

  )

  );

  oTable.setModel(oModel);

  oTable.bindRows({path: “/item/”});

// End of code

Assigned Tags

      11 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Fábio Luiz Esperati Pagoti
      Fábio Luiz Esperati Pagoti

      SAPUI5 provides very good integration with OData but not so easily with WebServices.

      Yes it does and they are known as JSONModel and XMLModel, which you have in your code snippets. It's easier when your services are REST based.

      Author's profile photo Amol Gupta
      Amol Gupta
      Blog Post Author

      Hi Fabio,

      Thanks for the proactive feedback, corrected it. But dont you think consuming OData services is much easier compared to Web Services ? For example you dont have to build Request XML or make an AJAX call. For a simple scenario with a couple of fields it is manageable but with a bigger real world application with numerous structures and fields, it is an extra overhead that needs extra coding effort which increases the chances of issues/bugs and  associated troubleshooting which in turn significantly  increases development turn around time.

      Regards,

      Amol Gupta

      Author's profile photo Fábio Luiz Esperati Pagoti
      Fábio Luiz Esperati Pagoti

      Hi Amol Gupta,

      Actually I don't think so. Comparing the effort of consumption between an oData service and a XML or JSON based service, the only thing that changes in your UI5 code is the name of the model class being used. Instead of ODataModel, you would use a XMLModel or JSONModel class. Such classes already make AJAX calls for you in order to get data. Your data binding should be the same assuming the services responses have all the same structure.

      Of course, if you consider not just data retrieval scenarios, when the consumer has to push some data to the server (POST, PUT, MERGE, etc), them of course you would have to do some extra AJAX calls yourself. Using jQuery this is almost effortless.

      However this is not a limitation from JSONModel or XMLModel classes. The point is that oData is a server based model class where XML and JSON are client based model classes. The oData protocol has more (known by the client) features comparing to random customized services. As a consequence, ODataModel class has more methods and more functionality.

      It would be extremely hard for UI5 developers to build JSON and XMLModel classes with "create", "update" or "delete" methods because the service might only work according to bizarre rules defined by the back end developer. Should the request contain a specific header? What are the HTTP methods supported by the server? Does it support other unicode? What is the content type? jQuery has already solved this issue.

      Concluding, IMO it does not change much for reading data. In order to solve CUD scenarios you will need more than client based models because well... they are just client based.

      Fábio Pagoti

      Author's profile photo anubha pandey
      anubha pandey

      Hi Amol, thanks for the blog. Even though I followed Kavya's blog, but was able to execute the ajax query and get response only after going through yours.

      Now, I am stuck at the stage - parsing the XML and get me output from response.

      Since I have only one field in output, it is easier for me to user DOM Parser.

      Could you please let me know, if I need to add below libraries to my controller.js file.

      Author's profile photo anubha pandey
      anubha pandey

      import javax.xml.parsers.*;

      Author's profile photo Prabh Simran Kaur
      Prabh Simran Kaur

      Hi Amol,

      After following the above steps , i get stuck data binding in Table. I am not sure where I am going wrong in setting the data

      Here is ajax call

      var oModel = new sap.ui.model.xml.XMLModel();

      $.ajax({

         url:"webservice url",

        type: "POST",

        data: request,

        dataType: "text",

        async: false,

           contentType: "text/xml; charset=\"utf-8\"",

        success: function(data, textStatus, jqXHR) {

        response = data;

      response = response.replace('<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">',"<documents>");

        response = response.replace('<tag>',"");

        response = response.replace("<soap-env:Header/>", "");                

        response = response.replace("<soap-env:Body>", "");     

        response = response.replace("</soap-env:Body>", "");  

        response = response.replace("<tag>","");

        response = response.replace("</soap-env:Envelope>", "</documents>");

        console.log("SUCCESS" + response);

        },

        error: function(xhr, status) {

        console.log("ERROR");

        },

        complete: function(xhr, status) {

        console.log("COMPLETE");

        oModel.setXML(response);

        }

        });

      <documents> root tag is added to overcome xml parsing error.

      I am directly setting this model in sap.m.Table control via .

      this.byId("tableId").setModel(oModel);

      Console shows oModel.getData as #document instead of object.

      /wp-content/uploads/2016/09/screenshot_1045727.jpg

      View.xml

      <Table id="resultTable" items="{path:'#document/documents/item/subitem'}">

        <columns>

        <Column>

        <Text text="SalesNo" id="sales"/>

        </Column>

        <Column>

        <Text text="Account" id="account"/>

        </Column>

        </columns>

        <items>

        <ColumnListItem type="Navigation" press="onPress">

        <cells>

        <Text text="{@SALESNO}"/>

        <Text text="{@ACCOUNT}"/>

        </cells>

        </ColumnListItem>

        </items>

        </Table>

      What path should be given in xml view to fetch the data returned by webservice in xml.format.

      Author's profile photo Prabh Simran Kaur
      Prabh Simran Kaur

      Thanks Amol,

      My problem is resolved and xml model data is also binded to control now.

      Thanks for helpful information sharing.

      Author's profile photo Former Member
      Former Member

      HI prabh how did you resolve this issue of #document binding?.I am also currently facing this issue

      Author's profile photo Jayakrishnan Chandramohan
      Jayakrishnan Chandramohan

      Hi ,

      I am trying to consume the same web service in my SAPUI5 application. It is showing the below mentioned error.

       

       

       

      And this is my controller code:

       

       

      Thank you,

      Regards,

      JK

       

       

      Author's profile photo Yen Shen, Ben Lim
      Yen Shen, Ben Lim

      Hi @Jayakrishnan Chandramohan

      I'm having the same issue, have you solved it?

      Author's profile photo Yen Shen, Ben Lim
      Yen Shen, Ben Lim

      Hi,

      I would like to ask is there any possibklity to create the web service url as SCP destination in order to solve the Access-Control-Allow-Origin problem?

      If yes, whats the configuration setting and the ajax coding part.

      Thanks.