on 02-09-2006 4:27 PM
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?
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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 ).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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!
I can HTTP post now, cheers guys.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
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.
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!
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¶m2=abcdef¶m3=%25+(+)+.
You will probably need to set the Content-Type to application/x-www-form-urlencoded.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello Robert,
perhaps this blogs could help you:
/people/durairaj.athavanraja/blog/2005/07/12/send-sms-to-india-from-abap
Regards
Frank
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
84 | |
24 | |
11 | |
9 | |
7 | |
6 | |
5 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.