cancel
Showing results for 
Search instead for 
Did you mean: 

Manual HTTP POST from ABAP

Former Member
0 Kudos

I'm trying to use a kind of botched web service implementation that doesn't come with a WSDL file - so, no generated proxy for me to use. It also needs me to send an XML file via an HTTP POST - not in a SOAP envelope. This presents a problem for me - understandably, this isn't part of WebAS 6.40's web services stuff.

Does anyone know of a way of manually posting something via HTTP in ABAP? I'm sure there must be some function module or class that exposes that functionality - I just can't find it! Any ideas anyone?

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Robert,

Yes I ahve done manual ABAP HTTP_POST from ABAP.

Check this blog , I have mentioned this in it.

/people/ankur.jain3/blog/2005/07/27/abap-java-marriage-made-in-heaven

***********The sample code **************

REPORT Z_HTTP_POST .

PARAMETERS : uri(100) lower case

default 'http://192.168.1.1:8181/ankur/testServlet' .

DATA: Status_code(5),

Status_text(300),

Len type I.

DATA: t_request_header type table of sbcheader with header line,

t_request_body type table of sbcbody with header line,

t_response_header type table of sbcheader with header line,

t_response_body type table of sbcbody with header line .

CALL FUNCTION 'HTTP_POST'

EXPORTING

ABSOLUTE_URI = Uri

REQUEST_ENTITY_BODY_LENGTH = 300

  • RFC_DESTINATION =

  • PROXY =

  • PROXY_USER =

  • PROXY_PASSWORD =

  • USER =

  • PASSWORD =

BLANKSTOCRLF = 'X'

IMPORTING

STATUS_CODE = Status_code

STATUS_TEXT = Status_text

RESPONSE_ENTITY_BODY_LENGTH = Len

TABLES

REQUEST_ENTITY_BODY = t_request_body

RESPONSE_ENTITY_BODY = t_response_body

RESPONSE_HEADERS = t_response_header

REQUEST_HEADERS = t_request_header

EXCEPTIONS

CONNECT_FAILED = 1

TIMEOUT = 2

INTERNAL_ERROR = 3

TCPIP_ERROR = 4

SYSTEM_FAILURE = 5

COMMUNICATION_FAILURE = 6

OTHERS = 7

Write:/ ‘the header data : ‘ .

Loop at t_response_header.

Write:/ t_response_header.

Endloop.

Skip(2).

Write:/ ‘the Body data : ‘ .

Loop at t_response_body.

Write:/ t_response_body.

Endloop.

athavanraja
Active Contributor
0 Kudos

check out this weblog.

/people/durairaj.athavanraja/blog/2004/09/20/consuming-web-service-from-abap

Regards

Raja

athavanraja
Active Contributor
0 Kudos

also check out this demo program

RSHTTP20

Regards

Raja

nagendran_r2
Explorer
0 Kudos

HI All,

I need to call a url which is more that 255 char .

so, i used http_post, but when i pass the parameter in the request body. its not getting updated...

what is the conent type i need to pass..

what should i do...

please help

Answers (5)

Answers (5)

Former Member
0 Kudos

Thanks a lot Robert!

I was already populating the parameters/values that way (after a lot of hit and trial errors ) but I still had the content type as 'text'. I changed it to 'application/form'. That made all the difference! For testing, right now I am just manually concatenating all the parameter/value pairs into a string. Did not use escape_url method.

Though I am getting a different kind of error now which I suspect is from the HTTP service side.

Former Member
0 Kudos

I tried using objects just as Rob Moss did, but I get no response back from web service at all. Am I missing something? Could it be problems with the format of my xml_out string? I formatted xml_out using:

CALL TRANSFORMATION ('ID')

SOURCE tab = gt_contacts[]

RESULT XML xml_out.

where gt_contacts[] is an ABAP internal table.

my objects code is as follows:

CREATE OBJECT xml_document.

CREATE OBJECT xml_response.

cl_http_client=>create_by_url( EXPORTING url = 'http://sapwsdl.dev.wolterskluwerfs.com/CRM_WS_ContactOutbound/CreateContactOutbound.asmx?wsdl' IMPORTING client = client EXCEPTIONS OTHERS = 1 ).

client->request->set_header_field( EXPORTING name = '~request_method' value = 'POST' ).

client->request->set_header_field( EXPORTING name = '~server_protocol' value = 'HTTP/1.1' ).

client->request->set_header_field( EXPORTING name = 'Content-Type' value = 'text/xml' ).

xml_document->render_2_string( EXPORTING pretty_print = 'X' IMPORTING stream = xml_out ).

client->request->set_cdata( EXPORTING data = xml_out offset = 0 ).

client->authenticate( EXPORTING proxy_authentication = space username = '' password = 't' ).

client->send( EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 ).

client->receive( EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 ).

xml_xstring = client->response->get_data( ).

zsubrc = xml_response->parse_xstring( stream = xml_xstring ).

Former Member
0 Kudos

I realise this reply is three years late, but I never received a notification of the reply via e-mail. So, whilst I'm here, in case anyone else stumbles across this, you should be using a consumer proxy (which you can create in SE80 - please see http://help.sap.com/saphelp_nw74/helpdata/en/47/9bcd5b65a9484be10000000a421138/content.htm?frameset=...) if you have a proper web service. My original question arose because what I had to use was not a real web service but simply a URL which expected XML documents in a particular format to be sent via HTTP POST and returned an XML document in another particular format. I'd much rather have had a real web service to use!

Former Member
0 Kudos

I can HTTP post now, cheers guys.

Former Member
0 Kudos

This, I decided, was a much better way of doing things - this is a method in a global class.

Interface:

xml_document type ref to cl_xml_document

method post_xml_document.

data: client type ref to if_http_client,

xml_response type ref to cl_xml_document.

data: xml_string type string,

xml_xstring type xstring.

data: zsubrc type sy-subrc.

cl_http_client=>create_by_url( exporting url = 'http://www.example.com/post-url.xml' importing client = client exceptions others = 1 ).

client->request->set_header_field( exporting name = '~request_method' value = 'POST' ).

client->request->set_header_field( exporting name = '~server_protocol' value = 'HTTP/1.1' ).

client->request->set_header_field( exporting name = 'Content-Type' value = 'text/xml' ).

xml_document->render_2_string( exporting pretty_print = 'X' importing stream = xml_string ).

client->request->set_cdata( exporting data = xml_string offset = 0 ).

client->authenticate( exporting proxy_authentication = space username = 'username' password = 'password' ).

client->send( exceptions http_communication_failure = 1 http_invalid_state = 2 ).

client->receive( exceptions http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 ).

xml_xstring = client->response->get_data( ).

zsubrc = xml_response->parse_xstring( stream = xml_xstring ).

endmethod.

No messing about with function modules, just pure unabated object-oriented goodness

former_member202771
Contributor
0 Kudos

Hi Robert,

Where are we passing the data in the above code.

this code helps us to post a document into a HTTP server. please correct me if I am wrong.

I need to place a text document into HTTP server.

Thanks,

Anil

Former Member
0 Kudos

Hi Anil,

The method I wrote takes an object reference of type cl_xml_document as input. It renders this as a string and then populates the content of the request with the client->request->set_cdata() method. You can pass in a string instead of the cl_xml_document typed object reference and place that in the set_cdata() method instead.

This doesn't upload a document to an HTTP server. It sends it in a POST request (please see http://tools.ietf.org/html/rfc2616#section-9.5). If you're trying to upload a document to an HTTP server, you will need to use a PUT request (please see http://tools.ietf.org/html/rfc2616#section-9.6). This would require your web server to be configured correctly in order to allow these requests. This is quite frequently not the case. Your only other option would be to write the file directly using OPEN DATASET filename FOR OUTPUT, or use FTP to upload the document to the web server's wwwroot folder.

Former Member
0 Kudos

Hi Robert,

It's been almost a year since your last reply, but thought I would try.

I am trying to post to an HTTP service. But instead of an XML form, I just have a list of parameters. I tried adding individual parameters using set_cdata(), but that does not seem to work.

Would you know how should I go about populating individual parameters?

Thanks!

Former Member
0 Kudos

Hi Leo,

No problem. Suppose you want to set the following parameters:

param1 = 123456

param2 = abcdef

param3 = % ( ) .

You need to URI-escape the parameters and their values, and then pass them via set_cdata in name/value pairs using '=' and '&'. You can use the escape() function in NW 7.31 and later, or CL_HTTP_UTILITY=>IF_HTTP_UTILITY~ESCAPE_URL() (I think that's right although I have no system to test it) in earlier releases. Replace %20 with plus signs after escaping. You should get something like this to pass to set_cdata():

param1=123456&param2=abcdef&param3=%25+(+)+.

You will probably need to set the Content-Type to application/x-www-form-urlencoded.

mandar_shete
Active Participant
0 Kudos

Hi,

You can get some idea from following code for your requirment


DATA: WA_DATA TYPE TSRCLIN,
      WA_RESULT TYPE TY_XML,
      WA_INV_REP TYPE TY_INV_REP,
      T_INV_REP TYPE TABLE OF TY_INV_REP,
      WA_ICA_REC_REP TYPE TY_ICA_REC_REP,
      T_ICA_REC_REP TYPE TABLE OF TY_ICA_REC_REP,
      T_RESULT TYPE T_XML,
      SOURCE_ITAB TYPE ABAP_TRANS_SRCBIND_TAB,
      SOURCE_WA   TYPE ABAP_TRANS_SRCBIND,
      WA_ZTICAUSER TYPE ZTICAUSER.

DATA: XSLTP TYPE REF TO CL_XSLT_PROCESSOR,
      G_IXML TYPE REF TO IF_IXML,
      G_STREAM_FACTORY TYPE REF TO IF_IXML_STREAM_FACTORY,
      G_ENCODING TYPE REF TO IF_IXML_ENCODING,
      RESSTR TYPE REF TO IF_IXML_OSTREAM,
      HTTP_CLIENT TYPE REF TO IF_HTTP_CLIENT .

DATA: SURL TYPE STRING.

DATA: WF_PROXY TYPE STRING ,
      WF_PORT TYPE STRING,
      WF_USER TYPE STRING,
      WF_PASSWORD TYPE STRING,
      RLENGTH TYPE I,
      R_CODE TYPE SY-SUBRC,
      USERID1 TYPE CHAR32.





CONSTANTS: ENCODING     TYPE STRING VALUE 'UTF-8',
           C_COMMA(1)               VALUE ',',
           C_AP(2)                  VALUE 'AP',
           C_AR(2)                  VALUE 'AR',
           C_CF(2)                  VALUE 'CF',
    CONV->READ( IMPORTING DATA = XMLSTRING LEN = LEN ).
    SPLIT XMLSTRING AT CL_ABAP_CHAR_UTILITIES=>CR_LF INTO TABLE T_DATA.


* Read Header Information
    READ TABLE T_DATA INDEX 1 INTO WA_DATA.
    SPLIT WA_DATA AT C_COMMA INTO DUMMY SOURCE_SYSTEM_ID DUMMY1.
    TRANSLATE DUMMY TO UPPER CASE.
    CONDENSE DUMMY.
    IF DUMMY <> 'SOURCE SYSTEM ID' OR SOURCE_SYSTEM_ID IS INITIAL.
      STRERROR = C_ERROR6.
    ELSE.
      DELETE T_DATA INDEX 1.
    ENDIF.

    CHECK STRERROR IS INITIAL.
    READ TABLE T_DATA INDEX 1 INTO WA_DATA.
    SPLIT WA_DATA AT C_COMMA INTO DUMMY DATE DUMMY1.
    TRANSLATE DUMMY TO UPPER CASE.
    CONDENSE DUMMY.
    IF DUMMY <> 'DATE' OR DATE IS INITIAL.
      STRERROR = C_ERROR6.
    ELSE.
      DELETE T_DATA INDEX 1.
    ENDIF.

    CHECK STRERROR IS INITIAL.
    READ TABLE T_DATA INDEX 1 INTO WA_DATA.
    SPLIT WA_DATA AT C_COMMA INTO DUMMY TIME DUMMY1.
    TRANSLATE DUMMY TO UPPER CASE.
    CONDENSE DUMMY.
    IF DUMMY <> 'TIME' OR TIME IS INITIAL.
      STRERROR = C_ERROR6.
    ELSE.
      DELETE T_DATA INDEX 1.
    ENDIF.

    CHECK STRERROR IS INITIAL.
    READ TABLE T_DATA INDEX 1 INTO WA_DATA.
    SPLIT WA_DATA AT C_COMMA INTO DUMMY CREATED_BY DUMMY1.
    TRANSLATE DUMMY TO UPPER CASE.
    CONDENSE DUMMY.
    IF DUMMY <> 'CREATED BY' OR CREATED_BY IS INITIAL.
      STRERROR = C_ERROR6.
    ELSE.
      DELETE T_DATA INDEX 1.
    ENDIF.

    CHECK STRERROR IS INITIAL.
    READ TABLE T_DATA INDEX 1 INTO WA_DATA.
    SPLIT WA_DATA AT C_COMMA INTO DUMMY TYPE DUMMY1.
    TRANSLATE DUMMY TO UPPER CASE.
    CONDENSE DUMMY.
    IF DUMMY <> 'TYPE' OR TYPE IS INITIAL.
      STRERROR = C_ERROR6.
    ELSE.
      CONDENSE TYPE.
      L_TYPE1 = REPGRP.
      L_TYPE2 = TYPE.
      TRANSLATE L_TYPE1 TO UPPER CASE.
      CONDENSE L_TYPE1.
      TRANSLATE L_TYPE2 TO UPPER CASE.
      CONDENSE L_TYPE2.

      IF L_TYPE1 NE L_TYPE2.
        IF L_TYPE2 = C_AP.
          CONCATENATE C_ERROR1_AP C_ERROR1
                      INTO STRERROR SEPARATED BY SPACE.
        ELSEIF L_TYPE2 = C_AR.
          CONCATENATE C_ERROR1_AR C_ERROR1
                      INTO STRERROR SEPARATED BY SPACE.
        ELSEIF L_TYPE2 = C_CF.
          CONCATENATE C_ERROR1_CF C_ERROR1
                      INTO STRERROR SEPARATED BY SPACE.
        ENDIF.
      ENDIF.
      DELETE T_DATA INDEX 1.
    ENDIF.

    CHECK STRERROR IS INITIAL.
    DELETE T_DATA INDEX 1.

    LOOP AT T_DATA INTO WA_DATA.
      SPLIT WA_DATA AT ',' INTO WA_RESULT-FITF
                                WA_RESULT-COUNTERPARTYFITF
                                WA_RESULT-FUCA
                                WA_RESULT-COUNTERPARTYFUCA
                                WA_RESULT-RECONCILIATIONACCOUNT
                                WA_RESULT-INDICATORCUSTOMERVENDOR
                                WA_RESULT-INVOICENUMBER
                                WA_RESULT-DOCUMENTDATE
                                WA_RESULT-POSTINGDATE
                                WA_RESULT-DUEDATE
                                WA_RESULT-INVOICEAMOUNT
                                WA_RESULT-INVOICECURRENCY
                                WA_RESULT-REPORTINGAMOUNT
                                WA_RESULT-REPORTINGCURRENCY
                                WA_RESULT-INDICATOR
                                WA_RESULT-CREATIONDATE
                                WA_RESULT-CLEARINGDATE.
                                
* Validation of the Structure.                                
                                
      WA_RESULT-SOURCESYSTEM = SOURCE_SYSTEM_ID.
      APPEND WA_RESULT TO T_RESULT.
      WA_INV_REP-INVOICEREPORT = WA_RESULT.
      WA_ICA_REC_REP-ICARECONCILIATIONREPORT = WA_INV_REP.
      WA_ICA_REC_REP-REPGRP = REPGRP.
      WA_ICA_REC_REP-NAMESPACE = C_STR.
      APPEND WA_ICA_REC_REP TO T_ICA_REC_REP.
    ENDLOOP.

    TRY.
        CREATE OBJECT XSLTP.
      CATCH CX_XSLT_EXCEPTION.
    ENDTRY.

    G_IXML = CL_IXML=>CREATE( ).
    G_STREAM_FACTORY = G_IXML->CREATE_STREAM_FACTORY( ).

****Create an Endcoding and Byte Order
    G_ENCODING = G_IXML->CREATE_ENCODING( CHARACTER_SET = ENCODING
      BYTE_ORDER = 0 ).

*****Create Output Stream
    RESSTR =
        G_STREAM_FACTORY->CREATE_OSTREAM_XSTRING( CONTENT ).

****Set the Encoding into a stream
    RESSTR->SET_ENCODING( ENCODING = G_ENCODING ).

* Prepare for Transformation
    SOURCE_WA-NAME = 'BSPXML'.
    GET REFERENCE OF T_ICA_REC_REP INTO SOURCE_WA-VALUE.
    APPEND SOURCE_WA TO SOURCE_ITAB.

    CLEAR XMLSTRING.
    CALL TRANSFORMATION Z_BSP_XSLT
    SOURCE (SOURCE_ITAB)
    RESULT XML XMLSTRING.
    IF SY-SUBRC <> 0.
      STRERROR = C_ERROR3.
    ENDIF.

    DATA: X1 TYPE STRING,
          X2 TYPE STRING.

* Change encoding from UTF-16 to UTF-8
    SPLIT XMLSTRING AT 'utf-16' INTO X1 X2.
    CLEAR XMLSTRING.
    CONCATENATE X1 'UTF-8' X2 INTO XMLSTRING.

    select single * into WA_ZTICAUSER
    from ZTICAUSER.
    if sy-subrc <> 0.
      clear WA_ZTICAUSER.
    endif.


 SURL = 'http://XXXXXYYYYY:8050/sap/xi/adapter_plain?'.
    CONCATENATE SURL
     'namespace=' 'http%3A//XXXX.com/corp/sapbw/fi/ica/xi111fn1'
                '&interface=' 'IOA_ICA_ReconciliationReport'
                '&service=' 'Send_ICA_ReconciliationReport'
                '&party=' 'ICA_ManualUpload'
                '&agency='
                '&scheme='
                '&QOS=EO&sap-user='  WA_ZTICAUSER-USERID 
                '&sap-password=' WA_ZTICAUSER-PTEXT 
                '&sap-client=' '060'
                '&sap-language=EN'
                INTO SURL.

* Test of XML file.
*    navigation->set_parameter( name = 'xmlstring'
*                               value = xmlstring ).
*    navigation->goto_page( 'XMLTest.xml' ).

* Navigation Code
    RLENGTH = STRLEN( XMLSTRING ).
    CL_HTTP_CLIENT=>CREATE_BY_URL( EXPORTING URL    = SURL
                               IMPORTING CLIENT = HTTP_CLIENT ).

    CALL METHOD HTTP_CLIENT->REQUEST->SET_HEADER_FIELD
      EXPORTING
        NAME  = 'Content-Type'
        VALUE = 'text/xml; charset=utf-8'.

    CALL METHOD HTTP_CLIENT->REQUEST->SET_HEADER_FIELD
      EXPORTING
        NAME  = '~request_method'
        VALUE = 'POST'.

    CALL METHOD HTTP_CLIENT->REQUEST->SET_CDATA
      EXPORTING
        DATA   = XMLSTRING
        OFFSET = 0
        LENGTH = RLENGTH.

    HTTP_CLIENT->SEND( ).
    HTTP_CLIENT->RECEIVE( ).
    HTTP_CLIENT->RESPONSE->GET_STATUS( IMPORTING CODE = RLENGTH ).
    XMLSTRING = HTTP_CLIENT->RESPONSE->GET_CDATA( ).
    HTTP_CLIENT->CLOSE( ).

    IF RLENGTH = '200'.
      STRERROR = C_SUCCESS.

* Update the information into the Table
      TRANSLATE SOURCE_SYSTEM_ID TO UPPER CASE.
      CONDENSE SOURCE_SYSTEM_ID.
      USERID1 = USERID.
      TRANSLATE USERID1 TO UPPER CASE.
      CONDENSE USERID1.
      CALL FUNCTION 'ZFM_BSP_ICA_UPLOAD'
        EXPORTING
          IV_SOURCE      = SOURCE_SYSTEM_ID
          IV_USERID      = USERID1
          IV_TYPE        = TYPE
*          IV_UPLOAD_DATE = SY-DATUM
*          IV_UPLOAD_TIME = SY-UZEIT
        IMPORTING
          R_CODE         = R_CODE.

    ELSE.
      STRERROR = C_ERROR4.
    ENDIF.

  ENDIF.
ENDIF.

Message was edited by: Mandar Shete

Former Member
0 Kudos

Hello Robert,

perhaps this blogs could help you:

/people/durairaj.athavanraja/blog/2005/07/12/send-sms-to-india-from-abap

Regards

Frank