You are on page 1of 11

Consuming WebServices with ABAP

Thomas Jung
Business Card
Company: SAP Labs, LLC
Posted on Nov. 17, 2004 10:44 AM in Business Server Pages, ABAP,
Application Server
Introduction
You might be thinking: how is consuming WebServices in ABAP really related to BSP . Is it because the WebAS and
the ICM (Internet Communication Manager) are at the core of both technologies? Or perhaps it is because you
might describe Consuming WebServices in ABAP as BSP turned inside out? When it comes right down to it, I
included this in BSP Weblog because for me using WebServices just goes hand-in-hand with the applications that I
happen to be developing in BSP. But don't feel that this technology is limited to BSP. In fact all the samples I am
going to share today run within good old traditional ABAP. There is even one with - gasp - just plain List Output
(talk about combining old technology with new!).
Release 620
First off there is no easy, good way of consuming SOAP WebServices in 620. There is a client API realized as an
ABAP Class Library. But if you read the SOAP Processor section on the service marketplace, you see that this
method in 620 is basically incompatible with release 640. You have to work directly with the SOAP request at a
fairly low level in the 620 API because proxy generation is not supported. All this and then you read the
statement: applications based on this interface therefore will face a considerable migration workload.
Automatic conversion will not be possible. Well that was enough to convince me to wait until 640 for full
SOAP WebServices.
I was faced with a problem. I have a requirement to build an application that sends SMS messages to cell phones
in Poland. Our SMS provider was only giving me the option of interfacing via a SOAP WebService. I needed the
working interface up in running by September 2004. But at this time, our 640 upgrade was more than 6 months
away. I didn't even have a copy of the install media yet! But as people in the area I live in are prone to say, there
is more than one way to skin a cat (makes you wonder what we do for fun around here). In 620 I may not have a
good SOAP WebService client, but I do have a HTTP Client. Meaning I can make HTTP requests and process the
response from ABAP. So why not simplify the interface by removing the SOAP. We make a request and on the URL
we specify certain parameters (SMS Number, Priority, Message, etc). The service provider processes the request
and sends us back a confirmation number and status in the response object. Little did we know at the time that
we were flirting in the SOAP vs. REST area of WebServices. Now I have never been the type of person to get
involved in theoretical debates about the potential uses of technology. I'm more of Git-'R-Done kind of guy. Does
the solution meet the requirements, budget, and timeline? Can I support it after we go live. If yes - then I say go
for it. If you are interested in the SOAP vs. REST debate you can find plenty of articles on the web (and a few
right here in SDN).
Configuration
Before we could really get started with this solution, we needed to configure a few things in the WebAS of course.
First we will be passing HTTP(s) out of our Corporate Network, across the public Internet, and finally reaching our
Service Provider (hopefully!). That means that like most corporations, we needed to configure our proxy settings
for passing through the firewall. You can find these settings in Transaction SICF under GOTO->HTTP Client Proxy.
You can probably just copy the same settings that you find in your web browser to complete these settings. If not
have a chat with your network administrator.
We are going to be using HTTPS for our communication. Therefore we need to add our provider's certificate to our
Trust Manager. We can do this from transaction STRUST. Choose Environment->SSL Client Identities from the
menu. This screen allows us to create a short SSL ID that we will attach our certificate to. We will also use this
same ID later in our ABAP code to include this certificate in our HTTP Processing. We can return to the main
screen in STRUST and upload their certificate. I had already navigated to the HTTPS URL that we would be using
with my Internet Explorer browser. Therefore all I had to do was go into Certificates Listing in IE and Export the
certificate. If you export as DER encoded binary X.509 (.CER) this matches up to the import option in SAP of File
Format Binary.
You then should see your certificate under your SSL ID with a green light.

Coding
We are ready to look at the coding now. We will break it down into little parts so that is can be easily digested.
First I implemented this functionality as a function module so that it can be called via RFC from our 46C R/3
system. I take in the SMS number, the Message Class, the Message, and the Priority as importing parameters. I
then pass back the unique SMS confirmation number, the status and the entire HTTP response as a string.
I wanted to make it easy to support different SMS providers or to make changes to the URL and SSL_ID; so ended
up setting up everything in a configuration table.

So we can then start of function module with a little bit of code to read the configuration settings from the config
table.

Next up I want to perform some checks on the input data. First I will check to make sure the message isn't too
long. Next up I want to check for Polish Characters. Even though we are going through a Polish SMS provider,
they asked us not to send any Polish National Characters. So we will use some SAP function modules to check the
codepage of the string and then transliterate any national characters back to ASCII7. Finally we will replace any +
in the SMS number and remove any spaces.

Next up is where things get really interesting. We will build our full Request URL by adding on all of the outbound
parameters. We create the client object for this URL.

Next up we set our request type to 'GET' and start the HTTP communications.
Now we are ready to receive the response back. We read it in character format. We then pull out the return
parameters from this response block.

In the end we have fairly simple approach to what could have been a complex problem. We leverage the ability of
the WebAS to act as an HTTP client and create an end result that functions very much like a WebService.
Release 640
If you really had your heart set on consuming SOAP WebServices from ABAP, you aren't out of luck. WebAS 640
comes along and makes the process relatively painless by offering the ability to generate proxy classes. Since this
technology is so new, I thought I might just build and walkthough a complete example here. I wanted to use a
public webservice that was available for free for several reasons. First I wanted to demonstrate how flexible the
technology was. Second I wanted anyone with a 640 system to be able to recreate the steps in this weblog on
their own with the same webservice. I found a nice collection of webservices at the following web address:
www.xmethods.com. I finally decided upon a simple service that returns book information when given an ISBN. It
even gives us the current price of the book at several on-line retailers. The Service Description can be found here:
http://www.winisp.net/cheeso/books/books.asmx.
Now that we have our webservice picked out, we are ready to generate our ABAP Proxy. To get the process
started, we turn to our old friend SE80. From the Enterprise Services Tab, we are going to select Client Proxy and
then hit create.

Next up we have to choose where our WSDL file is going to come from. We could connect directly to a UDDI
server or XI repository and query for our object. Or we might have saved the WSDL definition to a file on our local
machine. But in this case we are going to connect directly to the WSDL definition using the URL that we got from
our on-line search.
Now we are asked what Package (Development Class for those you upgrading from 46C or lower) we want to
place the generated object in as well as what prefix we want to use. I'm just playing around so I am going to
make the object Local Private by putting in my $TMP package. To follow SAP naming standards, as well as my
company's standards, I will get the object a prefix of ZES_ (In case you are wondering - the object starts with Z to
follow SAP's naming standard for customer development. The next letter E standard for Electronics - the division I
work for. Finally the S stands for Basis - the application area that this development belongs to.)

We have our generated Client Proxy. The following are some screen shots of what this should look like in SE80.
You can see that not only do we have an ABAP class, but the process also generated structures and table types to
represent all the importing and exporting data.
There is only one last thing we need to do to our Client Proxy before we are ready to use it: we need to configure
a Logical Port for it. We can do this in transaction LPCONFIG. We can configure more than one Logical Port and
specify the one we want at runtime. However for this solution we will just configure one port and make it the
default.

Inside the definition of the Logical Port we can adjust settings for the Client Proxy such as the URL we going to
call, the logging, State Management, etc. Since this is the default Logical Port, we will just save it with all the
settings that were imported from the WSDL definition.

We can then return to SE80 and perform a test on the WebService by hitting F8. We then get a dialog that allows
us to set parameters for our test.
We then choose which method we want to invoke. We are going to be using the GET_INFO method later in our
example, so let's test that.

Hopefully you get a success message like the following:

Once everything checks out OK in the test tool, we are ready to start programming against our Client Proxy. The
following program example has one parameter for supplying the ISBN. We then take this parameter and use it to
fill out the request object for our Client Proxy. After the call to the Client Proxy, all the returned data is contained
in our response object. The response object has the format of the generated table types and structures as defined
in the WSDL file. We can loop through this data and process as we see fit. For this case we are just going to
output a simple ABAP list.

Not too difficult at all. Let's test it real quick. I used ISBN 0201750805 to test with. If you perform the test you
should see ABAP Object Introduction to Programming SAP Application co-authored by fellow weblogger Horst
Keller.

Create a report program from se38 and copy/paste the code below.
REPORT y_sms_to_india620.
DATA: http_client TYPE REF TO if_http_client .
DATA: wf_string TYPE string ,
result TYPE string ,
r_str TYPE string .
DATA: result_tab TYPE TABLE OF string.
SELECTION-SCREEN: BEGIN OF BLOCK a WITH FRAME .
PARAMETERS: mail(100) LOWER CASE,
m_no(20) LOWER CASE ,
m_mss(120) LOWER CASE.
SELECTION-SCREEN: END OF BLOCK a .
START-OF-SELECTION .
CLEAR wf_string .
CONCATENATE
'http://www.webservicex.net/SendSMS.asmx/SendSMSToIndia?
MobileNumber='
m_no
'&FromEmailAddress='
mail
'&Message='
m_mss
INTO
wf_string .
CALL METHOD cl_http_client=>create_by_url
EXPORTING url = wf_string
IMPORTING client = http_client
EXCEPTIONS argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4.
CALL METHOD http_client->send
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2.
CALL METHOD http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3.
CLEAR result .
result = http_client->response->get_cdata( ).
REFRESH result_tab .
SPLIT result AT cl_abap_char_utilities=>cr_lf INTO TABLE result_tab .

LOOP AT result_tab INTO r_str.


WRITE:/ r_str .
ENDLOOP .

I tried this from Saudi Arabia to a BPL mobile at Trichy/India and it


works!

You might also like