Skip to Content

When I first experienced* GOOGLE’s ANDROID*, I was puzzled ’bout how to communicate with SAP without having to install something in my device…so,I look for some http client interfaces which could help me…simple and fast…

When my search failed, I decide to create my own http service to call ANY function in SAP system via HTTP, without having the restriction of RFC’s enabled ones.

 

I wish to share my experience, hoping it’ll be helpful to someone…

Access to SICF transaction and declare a new service; insert the service user which will be used by default to access to your system.

 In the tab ‘Handler List’ insert your+ Z class+ which implement the IF_HTTP_EXTENSION interface(create it if doesn’t already exist using SE24).

Save and activate the service.

Insert the following code in the IF_HTTP_EXTENSION~HANDLE_REQUEST method:

set extended check off.

type-pools ABAP.

data PARA_TAB type ABAP_FUNC_PARMBIND_TAB.

data: aus_para_tab type table of abap_func_parmbind,

      aus_line type abap_func_parmbind.

data PARA_LINE like line of PARA_TAB.

data AREA(4) type C.

data OBJECT(30) type C.

types: begin of import,

        name type string,

        value type string,

       end of import,

       begin of tables,

         name type string,

         row type string,

         field type string,

         value type string,

      end of tables.

  data: fbname_resp(200) type c.

  data: outsstr type string.

  data: outdoc type xstring,

        indoc  type xstring.

  data: fbname(40)  type c.

  data: fb_response type string.

  data: xform(50)   type c.

  data: xprog(50)   type c.

  data: tagtype     type i.

  data: exception   type string.

  data: nsattrib    type string.

  data: response    type string.

  data: header      type string.

  data: xmlheader   type string.

  data: begindoc    type string.

  data: enddoc      type string.

  data: beginfault  type string.

  data: endfault    type string.

  data: faultcode   type string.

  data: faultstring  type string.

  data: fault_detail type string.

  data: detail_name  type string.

  data: detail_msg   type string.

  data: dummy        type string.

  data: sy_subrc(2)  type c.

  data: tagname    type string,

        value      type string,

        xmlns      type string,

        attname    type string,

        attval     type string,

        attribcnt  type i,

        i          type i.

  data: raise_exception type c.

  data: content_type type string.

  data: templ_http_hdr    type string,

        templ_body        type string.

   data: cdata type string.

*&-Retrieving of characer data

  cdata = server->request->get_cdata( ).

*{   INSERT         SVIK909215                                        1

*data acca. while acca eq space. endwhile.

*}   INSERT

  if not cdata is initial.

  data:miniparser type ref to cl_ixml_mini_parser.

  data:minidom type ref to if_ixml_mini_dom.

  data rc type sy-subrc.

  data: nodename type string.

  data: node type ref to IF_IXML_MINI_NODE,

        newnode type ref to if_ixml_mini_node,

        nodeleaf type ref to if_ixml_mini_node,

        nvalue type ref to if_ixml_mini_node,

        nodetab type ref to if_ixml_mini_node,

        noderow type ref to if_ixml_mini_node,

        nodefield type ref to if_ixml_mini_node,

        funname type string,

        timport type table of import,

        ttables type table of tables,

        simport type import,

        stables type tables,

        rowindex(3) type n.

  data: responsexml type string,

                   viewname type DD02L-TABNAME,

                   tdfies type table of ddfield,

                   sdfies type ddfield,

                   valfield type char200.

  DATA: ITERATOR TYPE REF TO IF_IXML_MINI_DFS_ITER.

      CREATE OBJECT MINIPARSER.

      CALL METHOD MINIPARSER->PARSE_STRING

                   EXPORTING

                      STREAM = CDATA

                   IMPORTING

                       DOM = MINIDOM.

      iterator = minidom->get_dfs_iterator( ).

      while rc eq 0.

        nodename = iterator->get_name( ).

        node = iterator->get_node( ).

        case nodename.

          when ‘CALL_FUNCTION’.

            call method node->get_attribute

                     exporting

                        index = 1

                     importing

                        value = funname.

          when ‘EXPORTING’.

*&-

*&-          GESTIONE PARAMETRI IMPORTING

*&-

            newnode = node->get_first_child( ).

            simport-name = newnode->get_name( ).

            nvalue = newnode->get_first_child( ).

            if not nvalue is initial.

              simport-value = nvalue->get_value( ).

            endif.

            append simport to timport.

            nodeleaf = newnode.

            while 1 = 1.

             clear nodeleaf.

             nodeleaf = newnode->get_next( ).

             if nodeleaf is initial.

                exit.

             endif.

             simport-name = nodeleaf->get_name( ).

             simport-value = nodeleaf->get_value( ).

             append simport to timport.

             newnode = nodeleaf.

            endwhile.

           when ‘TABLES’.

*&-

*&-             GESTIONE TABLES

*&-

             nodetab = node->get_first_child( ).

             while 1 = 1. “tab

                 rowindex = 1.

                 if nodetab is initial. exit. endif.

                 stables-name = nodetab->get_name( ).

                 noderow = nodetab->get_first_child( ).

                   while 1 = 1 .”is initial.

                        stables-row = rowindex.

                        if noderow is initial. exit. endif.

                        nodefield = noderow->get_first_child( ).

                        while 1 = 1.

                               if nodefield is initial. exit. endif.

                               stables-field = nodefield->get_name( ).

                               nvalue = nodefield->get_first_child( ).

                               if not nvalue is initial.

                                stables-value = nvalue->get_value( ).

                               endif.

                               append stables to ttables.

                               nodefield = nodefield->get_next( ).

                        endwhile.

                        add 1 to rowindex.

                        noderow = noderow->get_next( ).

                   endwhile.

                nodetab = nodetab->get_next( ).

             endwhile.

        endcase.

        rc = iterator->advance( ).

      endwhile.

        data: texc type table of rsexc,

              sexc type rsexc,

              texp type table of rsexp,

              sexp type rsexp,

              timp type table of rsimp,

              simp type rsimp,

              tcha type table of rscha,

              scha type rscha,

              tpara type table of rstbl,

              spara type rstbl.

        data datatype type ref to data.

        data: funcname type RS38L-NAME.

        funcname = funname.

          CALL FUNCTION ‘FUNCTION_IMPORT_INTERFACE’

            EXPORTING

              funcname                 = funcname

  •             INACTIVE_VERSION         = ‘ ‘

  •           IMPORTING

  •             GLOBAL_FLAG              =

  •              REMOTE_CALL              =

  •             UPDATE_TASK              =

  •             EXCEPTION_CLASSES        =

            tables

              exception_list           = texc

              export_parameter         = texp

              import_parameter         = timp

              CHANGING_PARAMETER       = tcha

              tables_parameter         = tpara

  •             P_DOCU                   =

  •           EXCEPTIONS

  •             ERROR_MESSAGE            = 1

  •             FUNCTION_NOT_FOUND       = 2

  •             INVALID_NAME             = 3

  •             OTHERS                   = 4

                    .

              IF sy-subrc <> 0.

  •               MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  •                       WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

              ENDIF.

              field-symbols: ‘ into responsexml.

                      CALL FUNCTION ‘DD_NAMETAB_TO_DDFIELDS’

                        EXPORTING

  •                         KEYFIELDS       = ‘X’

  •                         NULLABLE        = ‘X’

                          tabname         = viewname

  •                       IMPORTING

  •                         SUBRC           =

                        tables

                          ddfields        = tdfies

                                .

                        looP AT tdfies into sdfies.

                          concatenate ‘.

              read table tpara into spara with key parameter = para_line-name.

                  if sy-subrc eq 0.

                    if not spara-dbstruct is initial.

                      viewname = spara-dbstruct.

                    elseif not spara-typ is initial.

                      typen = spara-typ.

                      CALL FUNCTION ‘DD_TTYP_GET’

                        EXPORTING

  •                         GET_STATE           = ‘M  ‘

  •                         LANGU               = SY-LANGU

  •                         PRID                = 0

                          ttyp_name           = typen

  •                         WITHTEXT            = ‘ ‘

  •                         TRACELEVEL          = 0

                       IMPORTING

                          DD40V_WA_A          = dd40wa

  •                         DD40V_WA_N          =

  •                         GOT_STATE           =

  •                       TABLES

  •                         DD42V_TAB_A         =

  •                         DD42V_TAB_N         =

  •                       EXCEPTIONS

  •                         ILLEGAL_VALUE       = 1

  •                         OP_FAILURE          = 2

  •                         OTHERS              = 3

                                .

                      IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  •         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

                      ENDIF.

                       viewname = dd40wa-rowtype.

                    endif.

                  endif.

              if not [] is initial.
concatenate responsexml ‘<‘ para_line-name ‘>

‘ into responsexml.

                  CALL FUNCTION ‘DD_NAMETAB_TO_DDFIELDS’

                    EXPORTING

  •                     KEYFIELDS       = ‘X’

  •                     NULLABLE        = ‘X’

                      tabname         = viewname

  •                   IMPORTING

  •                     SUBRC           =

                    tables

                      ddfields        = tdfies

                            .

                 loop at <CALL_FUNCTION name=”<functionname>”></p><p>*  <EXPORTING></p><p>       </p><p>       </p><p>       ….</p><p>        </p><p>   </p><p>      </p><p>        </p><p>        </p><p>        </p><p>        </row></p><p>     </NAMETAB1></p><p>     ….</p><p>     < /NAMETABn></p><p> </p><p>The server should invoke the function and answer with a similar format:</p><p><CALL_FUNCTION name=”<functionname>”></p><p>  </p><p>       </p><p>       </p><p>       ….</p><p>        </p><p>   </p><p>      </p><p>        </p><p>        </p><p>        </p><p>        </row></p><p>     </NAMETAB1></p><p>     ….</p><p>     < /NAMETABn>*

…Just as if you call a function from ABAP code… 

 

To report this post you need to login first.

5 Comments

You must be Logged on to comment or reply to a post.

    1. Paolo Romano Post author
      Thanks Ignacio…I’m sorry, I didn’t mention you but was your weblog “Android and SAP NetWeaver” that inspired this one!!!

      Best Regards and thanks again
      Paolo

      (0) 
  1. Andreas Vogel
    Interesting attempt. But actually your’re opening a security hole with a diameter like Jupiters orbit. There are plenty good reasons why not all functions are RFC enabled and therefore not reachable from outside. Furthermore your function avoids authority checks. Implementing this function violates surely all standards, guidelines, and policies.
    Regards, Andreas
    (0) 
    1. Paolo Romano Post author
      I know, Andreas. Actually, this service sample was intended for internal use and a study case, surely NOT to be accessed externally and widespreaded to open internet access.
      In this case,of course, one should implements major changes to the service: https, limit access via mapped (device) user, etc…
      Like all service of this kind, I think should be a developer’s tool, so I can’t understand why should’nt access to no-RFC enabled FM…
      regards
      Paolo
      (0) 

Leave a Reply