SharePoint API aus SAP aufrufen, Methode POST

Wie in dem vorherigen Beispiel beschrieben, kann über die SharePoint API auch ein Listenelement erstellt werden. Dazu wird ein HTTP Post Methodenaufruf verwendet. Dieser Aufruf erwartet im Header zwingend die Angabe eines X-RequestDigest. Dieser Wert kann mit der API /_api/contextinfo ermittelt werden.

Das folgende Beispiel zeigt, wie man ein Listenelement aus SAP heraus erstellen kann.

*&---------------------------------------------------------------------*
*& Report  Z_TEST_RESTFUL_SERVICE
*&
*&---------------------------------------------------------------------*
*&  SharePoint API aufrufen
*&  POST Methode aufrufen zum Erstellen eines Listenelements
*&---------------------------------------------------------------------*
REPORT z_test_restful_service_post.


DATA: lo_http_client        TYPE REF TO if_http_client,
      lv_service            TYPE string,
      lv_result             TYPE xstring,
      lv_validation         TYPE string,
      lo_nodes              TYPE REF TO if_ixml_node,
      lo_ixml_node_iterator TYPE REF TO if_ixml_node_iterator,
      lv_formdigestvalue    TYPE string,
      lo_proxy_xpath        TYPE REF TO cl_proxy_xpath,
      lv_xpath              TYPE string.
*----------------------------------------------------------------------------------------
*   X-RequestDigset lesen, erforderlich für SecurityValidation, nur bei POST Methoden
*----------------------------------------------------------------------------------------

lv_service     = 'http://<url>/sites/<my_site>/_api/contextinfo'.

" Http Client erstellen
cl_http_client=>create_by_url(
  EXPORTING
    url                = lv_service
  IMPORTING
    client             = lo_http_client
  EXCEPTIONS
    argument_not_found = 1
    plugin_not_active  = 2
    internal_error     = 3
    OTHERS             = 4 ).

" Methode setzen
lo_http_client->request->set_method( if_http_request=>co_request_method_post ).

" Protokollversion setzen
lo_http_client->request->set_version( if_http_request=>co_protocol_version_1_1 ).

" content type setzen
lo_http_client->request->set_content_type( 'application/json;odata=verbose' ).

" Header setzen
lo_http_client->request->set_header_field( name = 'accept' value = 'application/xml' ).
lo_http_client->request->set_header_field( name = 'content-type' value = 'application/json;odata=verbose;charset=utf-8' ).
"lo_http_client->request->set_header_field( name = 'connection' value = 'keep-alive' ).

" Anmeldung mittels BASIC Authentifizierung. DOMAIN\user:password als BASE64 codierung
lo_http_client->request->set_header_field( name = 'Authorization'
                                           value = 'Basic hereComesBase64String' ).

" HTTP Request senden
lo_http_client->send(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2 ).

" HTTP Response auswerten
lo_http_client->receive(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2
    http_processing_failed     = 3 ).

" XML Ergebnis lesen
lv_validation = lo_http_client->response->get_cdata( ).

" XPATH Query
lv_xpath = '/d:GetContextWebInformation/d:FormDigestValue'.

" XPATH Helper Klasse erstellen
lo_proxy_xpath = NEW #( ).

" XML zuweisen
lo_proxy_xpath->set_source_string( lv_validation ).

" XPATH durchführen. Übergabe von Query und Namespace Deklaration
lo_proxy_xpath->run( expression = lv_xpath
                       ns_decls = 'd http://schemas.microsoft.com/ado/2007/08/dataservices' ).

" Ergebnis des XPath auswerten
lo_ixml_node_iterator = lo_proxy_xpath->get_nodes( ).

IF lo_ixml_node_iterator IS NOT INITIAL.
  lo_nodes = lo_ixml_node_iterator->get_next( ).
  IF lo_nodes IS BOUND.
    lv_formdigestvalue =  lo_nodes->get_value( ).

  ENDIF.
ENDIF.

*----------------------------------------------------------------------------------------
*   POST Methode zum erstellen eines Listenelements aufrufen
*----------------------------------------------------------------------------------------

lv_service = 'http://<url>/sites/<my_site>/_api/web/lists/GetByTitle(' && |'| && 'MyListTitle' && |'| && ')/items'.

" eigentlicher Service (volle URL, aber ohne HOST)
lo_http_client->request->set_header_field( name = '~request_uri'
                                           value = '/sites/<my_site>/_api/web/lists/GetByTitle(' && |'| && 'MyListTitle' && |'| && ')/items'  ).

" security validation durch Übergabe X-RequestDigest
lo_http_client->request->set_header_field( name = 'x-requestdigest' value = lv_formdigestvalue ).

" Body
lo_http_client->request->append_cdata(
 ' {"__metadata":{"type":"SP.Data.MyListTitleListItem" },"Title":"Test von SAP"} ').


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

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

" XML Ergebnis lesen
CLEAR lv_result .
lv_result = lo_http_client->response->get_data( ).

" XML ausgeben
CALL FUNCTION 'SRTUTIL_HELPER_XML_SHOW'
  EXPORTING
    xdoc = lv_result
    html = abap_false. 

Hinweise

Authentifizierung

Im vorliegenden Beispiel erfolgt die Authentifizierung mittels HTTP Basic Authentication. Die Anmeldedaten lassen sich einfach über den HTTP Header übertragen. Dazu muss zunächst (z.B. Online tool) die Anmeldeinformation im BASE64 Codierung erzeugt werden. Die Anmeldeinformationen wie folgt codieren:

Domain\User:Passwort

 

HTTP Client

Im obigen Beispiel wird für beide HTTP Requests die gleiche Instant der CL_HTTP_CLIENT Klasse verwendet. Da verschiedene Services aufgerufen werden, muss im Header noch die ~request_uri angepasst werden.

Alternativ kann auch eine neue Instanz der CL_HTTP_CLIENT Klasse verwendet werden.