In dieser 4-Teiligen Blogreihe erfahren Sie alles nötige, um Media-Entity-Handling in SAP UI5 laut gängigen Best-Practice-Erfahrungen zu implementieren.
Einen tieferen Einblick in verschiedenste Themen gibt es in unseren Kursen bei Die Entdecker, die offiziell über training.sap.com angeboten werden.
Für diesen Blog interessante Trainings:

Inhalt
Im zweiten Schritt unserer OData-Journey erfahren wir alles nötige, um einen OData-Service für unsere Medien zu erstellen.
Wir werden einen SEGW-Projekt erstellen, einen OData-Service einrichten und die in Teil 1 erstellte CDS-View mappen. Außerdem werden wir noch die nötigen STREA-Methoden überschreiben und redefinieren.
Voraussetzungen:
- Eclipse
- ABAP Development Tools
Schritt 1 – OData-Service erstelleln
Damit wir unsere Media-Entries auch aus einer UI5-App heraus auslesen können, brauchen wir einen OData-Service, der diese Daten freigibt.
Dazu gehen wir in die SEGW – SAP Gateway Service Builder – und erstellen eine neues lokales Projekt.

Struktur importieren
Sobald der Service nun erstellt wurde, können wir eine neue Entity basieren auf unserer File-Struktur anlegen. Dazu per Rechtsklick eine ABAP-Dictionary-Struktur importieren.

Wir nennen unsere Entity File und geben unsere File-Struktur an.

Im folgenden Screen müssen die Felder ausgewählt werden, die in die Entity importiert werden sollen. Hier selektieren wir alle Felder bis auf den Mandanten, da wir diesen nicht freigeben wollen.

Anschließend wählen wir noch das Schlüsselfeld für unsere Entity aus.

Damit wir in den Metadaten des Services noch die Info bekommen, welche Entity eine Media-Entity ist, setzten wir das Flag Medium auf true.

CDS-View mappen
Damit wir uns die Redefinitionen der GET_ENTITY und der GET_ENTITYSET sparen, können wir die in Teil 1 erstellte CDS-View importieren. Diese nimmt und die Funktionalität der beiden GET-Methoden ab und ermöglicht Filterung und Sortierung.

Wir wählen eine Business Entity aus und geben unseren DDL-View-Namen an.

Wenn nun unsere CDS-View gefunden wurde, können die Felder der View den Feldern der Entity zugeordnet werden. Falls Navigation-Properties/Associations existieren, können diese hier ebenfalls gemappt werden.

DEFINE redefinieren
Damit unser OData-Service weiß, welche Entity eine Media-Entity ist, bzw ob hier eine Stream-Methode dahinter liegt, muss die DEFINE-Methode der Model-Provider-Class (MPC_EXT) redefiniert werden. Hier sagen wir, welche Entity eine Media-Entity ist.
Wichtig für uns:
- set_as_content_type
- Hier wird das Feld angegeben, das den Mime-Type der Datei beinhaltet.
- set_as_content_source
- Hier wird das Feld angegeben, das den Inhalt der Datei beinhaltet.

method DEFINE.
DATA: lo_entity TYPE REF TO /iwbep/if_mgw_odata_entity_typ.
DATA: lo_property TYPE REF TO /iwbep/if_mgw_odata_property.
super->define( ).
lo_entity = model->get_entity_type( iv_entity_name = ‚File‘ ).
IF lo_entity IS BOUND.
lo_property = lo_entity->get_property( iv_property_name = ‚Mimetype‘ ).
lo_property->set_as_content_type( ).
lo_property = lo_entity->get_property( iv_property_name = ‚Content‘ ).
lo_property->set_as_content_source( ).
ENDIF.
endmethod.
GET_STREAM redefinieren
Damit wir unsere Media-Entity als Datei geliefert bekommen, müssen wir die GET_STREAM-Methode der Data-Provider-Class (DPC_EXT) redefinieren. Hier selektieren wir mit dem übergebenen Schlüssel einen Eintrag unserer Tabelle und setzen die Response-Header.
Für uns wichtig:
- it_key_tab
- Tabelle mit den übergebenen Keys.
- ls_stream
- Struktur, in der der File-Stream mit Content und MimeType gespeichert werden.
- ls_header
- Struktur für den Response-Header

METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.
DATA: ls_key TYPE /iwbep/s_mgw_name_value_pair,
lv_fileid TYPE sysuuid_c,
ls_stream TYPE ty_s_media_resource,
ls_header TYPE ihttpnvp,
lv_filename TYPE string,
ls_file TYPE zdemo_file_s.
* Keys lesen
READ TABLE it_key_tab WITH KEY name = ‚Fileid‘ INTO ls_key.
lv_fileid = ls_key-value.
* File aus Datenbank lesen
SELECT SINGLE * FROM zdemo_file INTO @ls_file WHERE fileid = @lv_fileid.
IF sy-subrc <> 0.
mo_context->get_message_container( )->add_message_text_only(
iv_msg_type = ‚E‘
iv_msg_text = TEXT-003
).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
textid = /iwbep/cx_mgw_busi_exception=>business_error
message_container = mo_context->get_message_container( ).
ENDIF.
* Werte zuweißen
ls_stream-value = ls_file-content.
ls_stream-mime_type = ls_file-mimetype.
lv_filename = ls_file-filename.
lv_filename = escape(
val = lv_filename
format = cl_abap_format=>e_url
).
* Header setzen
ls_header-name = |content-disposition|.
ls_header-value = |inline; filename={ lv_filename }|.
set_header( is_header = ls_header ).
copy_data_to_ref(
EXPORTING
is_data = ls_stream
CHANGING
cr_data = er_stream ).
ENDMETHOD.
CREATE_STREAM überschreiben
Damit wir auch Files speichern können, überschreiben wir die CREATE_STREAM-Methode. In dieser erstellen wir einen neuen Eintrag in unserer Tabelle. Dazu benötigen wir eine GUID, die wir ebenfalls erstellen.
Für uns wichtig:
- create_uuid_c32_static
- Erstellt uns eine gültige UUID als Key für unseren Datensatz.
- copy_data_to_ref
- Kopiert die erstellten Daten in die zurückliefernde Struktur.
- iv_slug
- In dem sogenannten Slug-Header steht der Dateiname.

METHOD /iwbep/if_mgw_appl_srv_runtime~create_stream.
DATA: ls_file TYPE zdemo_file_s,
ls_key_tab TYPE /iwbep/s_mgw_name_value_pair,
lo_facade TYPE REF TO /iwbep/if_mgw_dp_int_facade,
lt_client_headers TYPE tihttpnvp,
ls_client_header LIKE LINE OF lt_client_headers,
lv_file_id TYPE sysuuid_c.
lo_facade ?= /iwbep/if_mgw_conv_srv_runtime~get_dp_facade( ).
lt_client_headers = lo_facade->get_request_header( ).
* UUID erstellen
TRY.
lv_file_id = cl_system_uuid=>create_uuid_c32_static( ).
CATCH cx_uuid_error INTO DATA(e_txt).
mo_context->get_message_container( )->add_message_text_only(
iv_msg_type = ‚E‘
iv_msg_text = TEXT-002
).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
textid = /iwbep/cx_mgw_busi_exception=>business_error
message_container = mo_context->get_message_container( ).
ENDTRY.
* Entity erstellen und mit Werten füllen
ls_file-fileid = lv_file_id.
ls_file-filename = iv_slug.
ls_file-content = is_media_resource-value.
ls_file-mimetype = is_media_resource-mime_type.
ls_file-creation_date = sy-datum.
ls_file-creation_time = sy-uzeit.
ls_file-created_by = sy-uname.
* Neuer Eintrag in die Datenbank
INSERT INTO zdemo_file VALUES ls_file.
IF sy-subrc <> 0.
mo_context->get_message_container( )->add_message_text_only(
iv_msg_type = ‚E‘
iv_msg_text = TEXT-001
).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
textid = /iwbep/cx_mgw_busi_exception=>business_error
message_container = mo_context->get_message_container( ).
ENDIF.
* Daten zurückgeben
copy_data_to_ref(
EXPORTING
is_data = ls_file
CHANGING
cr_data = er_entity ).
ENDMETHOD.
Service hinzufügen
Nachdem nun unser Servce fertig ist, müssen wir ihn in der Transation /IWFND/MAINT_SERVICE zu dem Service-Catalog hinzufügen.

Hier filtern wir nach dem Systemalias LOCAL und dem Technischen Servicenamen unserers Services.
Sobald er gefunden wurden, fügen wir den Service zu dem Service-Catalog hinzu.

Wir erstellen einen lokal laufenden Service.

Service testen
Sobald der Service im Service-Catalog aufscheint, können wir in im SAP Gateway Client testen.

Upload testen
Um ein File per OData-Service hochzuladen, müssen wir einen POST-Request auswählen.
Anschließend wählen wir unser FileSet aus.
Per Datei hinzufügen fügen wir ein Test-File zu unserem Request hinzu. Zusätzlich müssen wir noch den SLUG-Header vergeben.
Sobald wir den Request versendet haben und der mit dem HTTP-Status 201 durchgelaufen ist, sehen wir eine Response, die das gespeicherte/hochgeladene File enthält.

Download testen
Wenn wir einen GET-Request mit einer URI auf eine existierende Entity mit dem Parameter $value versenden, bekommen wir das gespeicherte File zurückgeliefert.
Der Parameter $value signalisiert, dass die GET_STREAM-Methode dieser Entity aufgerufen wird. Das Resultat können wir uns per Antwort in Browser im Browser anzeigen lassen.

Testen per OData-Plugin
Das Testen von OData-Services geht ebenfalls mit dem CloudDNA OData-Plugin bequem aus der WebIDE.
Hier kann die unsere File-Entity getestet werden. Nach unserem Request bekommen wir auch noch Zusatzinformationen zu dem Request wie Header, Parameters etc.

Das Testen von Upload-Funktionalitäten geht ebenfalls einfach per File-Uploader. Sollten wir etwas im Backend nicht richtig implementiert haben, bekommen wir hier eine Fehlermeldung. Außerdem brauchen wir uns nicht um das Setzen von Slug und XCSRF-Token kümmern.

Zusammenfassung
Die Hälfte ist geschafft.
In Teil 2 haben wir nun einen OData-Service basierend auf den Daten von Teil 1 erstellt. Diesen Odata-Service werden wir in Teil 3 benötigen, um die UploadCollection ins Laufen zu bringen.
Falls Fragen zu diesen einzelnen Schritten auftreten, können sie gerne in den Kommentaren gestellt werden.
Recent Comments