SOAP Web Services konsumieren in ABAP Cloud

kategorie
Integration
Veröffentlicht
autor
Johannes

SOAP Web Services sind trotz des Trends zu REST weiterhin in vielen Unternehmensumgebungen verbreitet. In ABAP Cloud erfolgt der Zugriff auf SOAP-Services über das Service Consumption Model, das typsichere Proxy-Klassen aus WSDL-Dateien generiert.

SOAP in ABAP Cloud vs. Klassisches ABAP

Die SOAP-Integration in ABAP Cloud unterscheidet sich grundlegend vom klassischen Ansatz:

AspektKlassisches ABAPABAP Cloud
Proxy-GenerierungSE80 / SPROXYADT Service Consumption Model
KonfigurationSOAMANAGERCommunication Arrangement
AuthentifizierungIn SOAMANAGEROAuth2, Zertifikate, Basic Auth
WSDL-ImportOnline oder lokalLokale Datei im ADT
TransportTransportauftragGit-basiert (gCTS)
RuntimeABAP Web Service FrameworkCloud-native SOAP Client

Service Consumption Model erstellen

Das Service Consumption Model ist der zentrale Baustein für SOAP in ABAP Cloud. Es generiert aus einer WSDL-Datei alle benötigten Artefakte.

Übersicht der generierten Artefakte

┌──────────────────────────────────────────────────────────────┐
│ Service Consumption Model: Z_CURRENCY_SOAP │
├──────────────────────────────────────────────────────────────┤
│ │
│ Aus WSDL generiert: │
│ ├── Proxy-Klasse: ZCL_PRXY_CURRENCY_SERVICE │
│ │ └── Methoden für jede WSDL-Operation │
│ ├── Datentypen (ABAP Dictionary) │
│ │ ├── ZST_CURRENCY_REQUEST │
│ │ ├── ZST_CURRENCY_RESPONSE │
│ │ └── ZST_CURRENCY_FAULT │
│ └── Exception-Klasse │
│ └── ZCX_PRXY_CURRENCY_SERVICE │
│ │
│ Manuell zu erstellen: │
│ ├── Communication Scenario │
│ ├── Communication System │
│ └── Communication Arrangement │
└──────────────────────────────────────────────────────────────┘

Schritt 1: WSDL-Datei beschaffen

Die WSDL-Datei beschreibt den SOAP-Service vollständig:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://example.com/currency"
targetNamespace="http://example.com/currency">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ConvertCurrencyRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="Amount" type="xs:decimal"/>
<xs:element name="FromCurrency" type="xs:string"/>
<xs:element name="ToCurrency" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ConvertCurrencyResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="ConvertedAmount" type="xs:decimal"/>
<xs:element name="ExchangeRate" type="xs:decimal"/>
<xs:element name="Timestamp" type="xs:dateTime"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="ConvertCurrencyInput">
<wsdl:part name="parameters" element="tns:ConvertCurrencyRequest"/>
</wsdl:message>
<wsdl:message name="ConvertCurrencyOutput">
<wsdl:part name="parameters" element="tns:ConvertCurrencyResponse"/>
</wsdl:message>
<wsdl:portType name="CurrencyServicePortType">
<wsdl:operation name="ConvertCurrency">
<wsdl:input message="tns:ConvertCurrencyInput"/>
<wsdl:output message="tns:ConvertCurrencyOutput"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CurrencyServiceBinding" type="tns:CurrencyServicePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="ConvertCurrency">
<soap:operation soapAction="ConvertCurrency"/>
<wsdl:input><soap:body use="literal"/></wsdl:input>
<wsdl:output><soap:body use="literal"/></wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CurrencyService">
<wsdl:port name="CurrencyServicePort" binding="tns:CurrencyServiceBinding">
<soap:address location="https://api.example.com/currency"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

Schritt 2: Service Consumption Model in ADT anlegen

  1. Rechtsklick auf Paket → NewOther ABAP Repository Object
  2. ConnectivityService Consumption Model auswählen
  3. Wizard durchlaufen:
┌──────────────────────────────────────────────────────────────┐
│ New Service Consumption Model │
├──────────────────────────────────────────────────────────────┤
│ Name: Z_CURRENCY_SOAP │
│ Description: Currency Conversion SOAP Service │
│ Package: Z_INTEGRATION │
│ │
│ Service Type: ○ OData │
│ ● Web Service (SOAP) │
│ ○ RFC │
│ │
│ WSDL File: [Browse...] currency_service.wsdl │
└──────────────────────────────────────────────────────────────┘

Schritt 3: Generierte Artefakte prüfen

Nach der Generierung enthält das Service Consumption Model:

Proxy-Klasse:

CLASS zcl_prxy_currency_service DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_proxy_client.
METHODS constructor
IMPORTING
!destination TYPE REF TO if_http_destination OPTIONAL.
METHODS convert_currency
IMPORTING
!input TYPE zst_convert_currency_request
RETURNING
VALUE(result) TYPE zst_convert_currency_response
RAISING
zcx_prxy_currency_service
cx_ai_system_fault.
ENDCLASS.

Request-Struktur:

TYPES: BEGIN OF zst_convert_currency_request,
amount TYPE decfloat34,
from_currency TYPE c LENGTH 3,
to_currency TYPE c LENGTH 3,
END OF zst_convert_currency_request.

Response-Struktur:

TYPES: BEGIN OF zst_convert_currency_response,
converted_amount TYPE decfloat34,
exchange_rate TYPE decfloat34,
timestamp TYPE timestamp,
END OF zst_convert_currency_response.

Communication Scenario einrichten

Für die SOAP-Verbindung wird ein Communication Scenario benötigt.

Communication Scenario anlegen

┌──────────────────────────────────────────────────────────────┐
│ Communication Scenario: Z_CURRENCY_SOAP_CS │
├──────────────────────────────────────────────────────────────┤
│ Communication Type: Outbound │
│ │
│ Outbound Services: │
│ └── Z_CURRENCY_SOAP_OS │
│ ├── Service Type: SOAP │
│ ├── Endpoint: /CurrencyService │
│ └── Authentication: Basic / OAuth2 / Certificate │
│ │
│ Supported Authentication Methods: │
│ ├── [x] Basic Authentication │
│ ├── [x] OAuth 2.0 Client Credentials │
│ └── [x] Client Certificate │
└──────────────────────────────────────────────────────────────┘

Communication System konfigurieren

┌──────────────────────────────────────────────────────────────┐
│ Communication System: CURRENCY_API_SYSTEM │
├──────────────────────────────────────────────────────────────┤
│ General Data: │
│ ├── System ID: CURRENCY │
│ ├── System Name: Currency Conversion API │
│ └── System Type: External System │
│ │
│ Technical Data: │
│ ├── Host: api.currencyservice.com │
│ ├── Port: 443 │
│ └── Path Prefix: /soap/v1 │
│ │
│ User for Outbound Communication: │
│ ├── Authentication Method: Basic Authentication │
│ ├── User Name: API_USER │
│ └── Password: ******** │
└──────────────────────────────────────────────────────────────┘

Communication Arrangement aktivieren

┌──────────────────────────────────────────────────────────────┐
│ Communication Arrangement: Z_CURRENCY_SOAP_PROD │
├──────────────────────────────────────────────────────────────┤
│ Communication Scenario: Z_CURRENCY_SOAP_CS │
│ Communication System: CURRENCY_API_SYSTEM │
│ │
│ Outbound Services: │
│ └── Z_CURRENCY_SOAP_OS: Active ✓ │
│ ├── Service URL: https://api.currencyservice.com/soap │
│ └── SOAP Action: Automatic │
│ │
│ Connection Test: [Test Connection] ✓ Successful │
└──────────────────────────────────────────────────────────────┘

SOAP Service aufrufen

Einfacher Aufruf

CLASS zcl_currency_converter DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES: BEGIN OF ty_conversion_result,
amount TYPE decfloat34,
currency TYPE waers,
exchange_rate TYPE decfloat34,
timestamp TYPE timestamp,
END OF ty_conversion_result.
METHODS convert_currency
IMPORTING
iv_amount TYPE decfloat34
iv_from_currency TYPE waers
iv_to_currency TYPE waers
RETURNING
VALUE(rs_result) TYPE ty_conversion_result
RAISING
zcx_currency_error.
ENDCLASS.
CLASS zcl_currency_converter IMPLEMENTATION.
METHOD convert_currency.
" HTTP-Destination aus Communication Arrangement holen
DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'Z_CURRENCY_SOAP_CS'
service_id = 'Z_CURRENCY_SOAP_OS' ).
" Proxy-Instanz mit Destination erstellen
DATA(lo_proxy) = NEW zcl_prxy_currency_service(
destination = lo_destination ).
" Request aufbauen
DATA(ls_request) = VALUE zst_convert_currency_request(
amount = iv_amount
from_currency = iv_from_currency
to_currency = iv_to_currency ).
TRY.
" SOAP-Aufruf durchführen
DATA(ls_response) = lo_proxy->convert_currency( input = ls_request ).
" Ergebnis mappen
rs_result = VALUE #(
amount = ls_response-converted_amount
currency = iv_to_currency
exchange_rate = ls_response-exchange_rate
timestamp = ls_response-timestamp ).
CATCH zcx_prxy_currency_service INTO DATA(lx_proxy).
" SOAP Fault vom Service
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING
previous = lx_proxy
textid = zcx_currency_error=>soap_fault.
CATCH cx_ai_system_fault INTO DATA(lx_system).
" Technischer Fehler (Netzwerk, Timeout)
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING
previous = lx_system
textid = zcx_currency_error=>system_error.
ENDTRY.
ENDMETHOD.
ENDCLASS.

Verwendung in Anwendungslogik

" In einer RAP-Action oder Determination
TRY.
DATA(lo_converter) = NEW zcl_currency_converter( ).
DATA(ls_result) = lo_converter->convert_currency(
iv_amount = 100
iv_from_currency = 'EUR'
iv_to_currency = 'USD' ).
" Ergebnis verwenden
DATA(lv_usd_amount) = ls_result-amount.
DATA(lv_rate) = ls_result-exchange_rate.
CATCH zcx_currency_error INTO DATA(lx_error).
" Fehlerbehandlung
APPEND VALUE #(
%tky = ls_key-%tky
%msg = new_message_with_text( text = lx_error->get_text( ) )
) TO reported-entity.
ENDTRY.

Authentifizierungsmethoden

Basic Authentication

Die einfachste Methode für geschützte SOAP-Services:

Communication System:
├── User for Outbound Communication
│ ├── Authentication Method: Basic Authentication
│ ├── User Name: SOAP_API_USER
│ └── Password: ********

Die Credentials werden automatisch als HTTP Basic Auth Header gesendet:

Authorization: Basic U09BUF9BUElfVVNFUjpwYXNzd29yZA==

OAuth 2.0 Client Credentials

Für moderne SOAP-Services mit Token-basierter Authentifizierung:

┌──────────────────────────────────────────────────────────────┐
│ Communication System: CURRENCY_API_OAUTH │
├──────────────────────────────────────────────────────────────┤
│ OAuth 2.0 Settings: │
│ ├── Grant Type: Client Credentials │
│ ├── Token Endpoint: https://auth.api.com/oauth/token │
│ ├── Client ID: abap-cloud-client │
│ ├── Client Secret: ******** │
│ └── Scope: currency.read currency.convert │
│ │
│ Token wird automatisch abgerufen und gecached │
└──────────────────────────────────────────────────────────────┘

Client Certificate

Für hochsichere Umgebungen mit gegenseitiger TLS-Authentifizierung:

Communication System:
├── User for Outbound Communication
│ ├── Authentication Method: Client Certificate
│ └── Certificate: [Upload X.509 Certificate]
└── Trust Configuration
└── Server Certificate: [Upload CA Certificate]

Fehlerbehandlung

SOAP Faults verarbeiten

SOAP-Services können strukturierte Fehlermeldungen (Faults) zurückgeben:

CLASS zcx_currency_error DEFINITION
PUBLIC
INHERITING FROM cx_static_check
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_t100_message.
CONSTANTS:
BEGIN OF soap_fault,
msgid TYPE symsgid VALUE 'Z_CURRENCY',
msgno TYPE symsgno VALUE '001',
attr1 TYPE scx_attrname VALUE 'MV_FAULT_CODE',
attr2 TYPE scx_attrname VALUE 'MV_FAULT_STRING',
attr3 TYPE scx_attrname VALUE '',
attr4 TYPE scx_attrname VALUE '',
END OF soap_fault,
BEGIN OF system_error,
msgid TYPE symsgid VALUE 'Z_CURRENCY',
msgno TYPE symsgno VALUE '002',
attr1 TYPE scx_attrname VALUE '',
attr2 TYPE scx_attrname VALUE '',
attr3 TYPE scx_attrname VALUE '',
attr4 TYPE scx_attrname VALUE '',
END OF system_error,
BEGIN OF timeout_error,
msgid TYPE symsgid VALUE 'Z_CURRENCY',
msgno TYPE symsgno VALUE '003',
attr1 TYPE scx_attrname VALUE '',
attr2 TYPE scx_attrname VALUE '',
attr3 TYPE scx_attrname VALUE '',
attr4 TYPE scx_attrname VALUE '',
END OF timeout_error.
DATA mv_fault_code TYPE string READ-ONLY.
DATA mv_fault_string TYPE string READ-ONLY.
METHODS constructor
IMPORTING
!textid LIKE if_t100_message=>t100key OPTIONAL
!previous LIKE previous OPTIONAL
!fault_code TYPE string OPTIONAL
!fault_string TYPE string OPTIONAL.
ENDCLASS.
CLASS zcx_currency_error IMPLEMENTATION.
METHOD constructor.
super->constructor( previous = previous ).
mv_fault_code = fault_code.
mv_fault_string = fault_string.
IF textid IS INITIAL.
if_t100_message~t100key = soap_fault.
ELSE.
if_t100_message~t100key = textid.
ENDIF.
ENDMETHOD.
ENDCLASS.

Detaillierte Fehlerauswertung

METHOD call_soap_with_error_handling.
TRY.
DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'Z_CURRENCY_SOAP_CS'
service_id = 'Z_CURRENCY_SOAP_OS' ).
DATA(lo_proxy) = NEW zcl_prxy_currency_service( destination = lo_destination ).
DATA(ls_response) = lo_proxy->convert_currency( input = ls_request ).
CATCH zcx_prxy_currency_service INTO DATA(lx_soap_fault).
" SOAP Fault - Fachlicher Fehler vom Service
" z.B. ungültige Währung, Betrag außerhalb Bereich
DATA(lv_fault_code) = lx_soap_fault->get_fault_code( ).
DATA(lv_fault_string) = lx_soap_fault->get_fault_string( ).
CASE lv_fault_code.
WHEN 'INVALID_CURRENCY'.
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING
textid = zcx_currency_error=>soap_fault
fault_code = lv_fault_code
fault_string = lv_fault_string.
WHEN 'RATE_NOT_AVAILABLE'.
" Retry mit anderem Datum oder Default-Kurs
rs_result = get_fallback_rate( ls_request ).
WHEN OTHERS.
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING previous = lx_soap_fault.
ENDCASE.
CATCH cx_http_dest_provider_error INTO DATA(lx_dest).
" Destination nicht gefunden oder falsch konfiguriert
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING
textid = zcx_currency_error=>system_error
previous = lx_dest.
CATCH cx_ai_system_fault INTO DATA(lx_system).
" Technischer Fehler: Netzwerk, Timeout, Parsing
IF lx_system->get_text( ) CS 'timeout'.
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING textid = zcx_currency_error=>timeout_error.
ELSE.
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING
textid = zcx_currency_error=>system_error
previous = lx_system.
ENDIF.
ENDTRY.
ENDMETHOD.

Retry-Logik für transiente Fehler

CLASS zcl_soap_retry_handler DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
CONSTANTS: c_max_retries TYPE i VALUE 3,
c_retry_delay TYPE i VALUE 1000, " ms
c_backoff_mult TYPE decfloat16 VALUE '1.5'.
METHODS call_with_retry
IMPORTING
is_request TYPE zst_convert_currency_request
RETURNING
VALUE(rs_result) TYPE zst_convert_currency_response
RAISING
zcx_currency_error.
ENDCLASS.
CLASS zcl_soap_retry_handler IMPLEMENTATION.
METHOD call_with_retry.
DATA: lv_retries TYPE i,
lv_delay TYPE i.
lv_delay = c_retry_delay.
WHILE lv_retries < c_max_retries.
TRY.
DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'Z_CURRENCY_SOAP_CS'
service_id = 'Z_CURRENCY_SOAP_OS' ).
DATA(lo_proxy) = NEW zcl_prxy_currency_service( destination = lo_destination ).
rs_result = lo_proxy->convert_currency( input = is_request ).
" Erfolg - sofort zurück
RETURN.
CATCH cx_ai_system_fault INTO DATA(lx_system).
" Nur bei transienten Fehlern retry
IF is_transient_error( lx_system ).
lv_retries = lv_retries + 1.
IF lv_retries < c_max_retries.
" Exponentielles Backoff
cl_abap_session_context=>sleep( lv_delay ).
lv_delay = CONV i( lv_delay * c_backoff_mult ).
ENDIF.
ELSE.
" Permanenter Fehler - kein Retry
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING previous = lx_system.
ENDIF.
CATCH zcx_prxy_currency_service INTO DATA(lx_soap).
" SOAP Faults sind fachliche Fehler - kein Retry
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING previous = lx_soap.
ENDTRY.
ENDWHILE.
" Max Retries erreicht
RAISE EXCEPTION TYPE zcx_currency_error
EXPORTING textid = zcx_currency_error=>timeout_error.
ENDMETHOD.
METHOD is_transient_error.
" Transiente Fehler: Timeout, Verbindung abgebrochen, Service temporär nicht verfügbar
DATA(lv_text) = to_lower( ix_error->get_text( ) ).
rv_result = xsdbool(
lv_text CS 'timeout' OR
lv_text CS 'connection' OR
lv_text CS '503' OR
lv_text CS 'temporarily' ).
ENDMETHOD.
ENDCLASS.

Integration mit RAP

Custom Entity für SOAP-Daten

@EndUserText.label: 'Währungskurse (extern)'
@ObjectModel.query.implementedBy: 'ABAP:ZCL_CE_CURRENCY_RATES'
define custom entity ZCE_CURRENCY_RATES
{
key FromCurrency : abap.char(3);
key ToCurrency : abap.char(3);
ExchangeRate : abap.dec(15,6);
LastUpdated : timestamp;
}

Query Implementation

CLASS zcl_ce_currency_rates DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_rap_query_provider.
ENDCLASS.
CLASS zcl_ce_currency_rates IMPLEMENTATION.
METHOD if_rap_query_provider~select.
" Filter auswerten
DATA(lt_filters) = io_request->get_filter( )->get_as_ranges( ).
" SOAP Service aufrufen
TRY.
DATA(lo_converter) = NEW zcl_currency_converter( ).
DATA lt_result TYPE STANDARD TABLE OF zce_currency_rates.
" Für jede Filterkombination Kurs abrufen
LOOP AT lt_filters INTO DATA(ls_filter)
WHERE name = 'FROMCURRENCY'.
DATA(lr_from) = ls_filter-range.
DATA(lr_to) = VALUE #( lt_filters[ name = 'TOCURRENCY' ]-range OPTIONAL ).
" SOAP aufrufen und Ergebnis mappen
DATA(ls_soap_result) = lo_converter->convert_currency(
iv_amount = 1
iv_from_currency = CONV #( lr_from[ 1 ]-low )
iv_to_currency = CONV #( lr_to[ 1 ]-low ) ).
APPEND VALUE #(
FromCurrency = lr_from[ 1 ]-low
ToCurrency = lr_to[ 1 ]-low
ExchangeRate = ls_soap_result-exchange_rate
LastUpdated = ls_soap_result-timestamp
) TO lt_result.
ENDLOOP.
io_response->set_total_number_of_records( lines( lt_result ) ).
io_response->set_data( lt_result ).
CATCH zcx_currency_error INTO DATA(lx_error).
RAISE EXCEPTION TYPE cx_rap_query_provider
EXPORTING previous = lx_error.
ENDTRY.
ENDMETHOD.
ENDCLASS.

RAP Action mit SOAP-Aufruf

" Behavior Definition
define behavior for ZI_ORDER alias Order
{
action convertCurrency parameter ZA_CURRENCY_PARAM result [1] $self;
}
" Behavior Implementation
CLASS lhc_order DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS convert_currency FOR MODIFY
IMPORTING keys FOR ACTION Order~convertCurrency RESULT result.
ENDCLASS.
CLASS lhc_order IMPLEMENTATION.
METHOD convert_currency.
" Bestellungen lesen
READ ENTITIES OF zi_order IN LOCAL MODE
ENTITY Order
FIELDS ( OrderID TotalAmount Currency )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_orders).
TRY.
DATA(lo_converter) = NEW zcl_currency_converter( ).
LOOP AT lt_orders INTO DATA(ls_order).
DATA(ls_key) = keys[ %tky = ls_order-%tky ].
" Währungsumrechnung via SOAP
DATA(ls_conversion) = lo_converter->convert_currency(
iv_amount = ls_order-TotalAmount
iv_from_currency = ls_order-Currency
iv_to_currency = ls_key-%param-TargetCurrency ).
" Entität aktualisieren
MODIFY ENTITIES OF zi_order IN LOCAL MODE
ENTITY Order
UPDATE FIELDS ( TotalAmount Currency )
WITH VALUE #( (
%tky = ls_order-%tky
TotalAmount = ls_conversion-amount
Currency = ls_key-%param-TargetCurrency ) ).
" Ergebnis zurückgeben
APPEND VALUE #(
%tky = ls_order-%tky
%param = CORRESPONDING #( ls_order )
) TO result.
ENDLOOP.
CATCH zcx_currency_error INTO DATA(lx_error).
LOOP AT keys INTO ls_key.
APPEND VALUE #(
%tky = ls_key-%tky
%msg = new_message_with_text( text = lx_error->get_text( ) )
) TO reported-order.
ENDLOOP.
ENDTRY.
ENDMETHOD.
ENDCLASS.

Komplexe SOAP-Szenarien

SOAP mit Attachments (MTOM)

Manche SOAP-Services verwenden MTOM (Message Transmission Optimization Mechanism) für binäre Daten:

" WSDL mit MTOM-Attachment
" Die generierte Proxy-Klasse behandelt MTOM automatisch
METHOD upload_document.
DATA(ls_request) = VALUE zst_upload_doc_request(
file_name = 'report.pdf'
content_type = 'application/pdf'
binary_data = lv_pdf_xstring ). " XSTRING wird als MTOM gesendet
DATA(ls_response) = lo_proxy->upload_document( input = ls_request ).
ENDMETHOD.

SOAP mit WS-Security

Für SOAP-Services mit WS-Security-Header:

Communication System:
├── Security Settings
│ ├── WS-Security: Enabled
│ ├── Username Token: API_USER
│ ├── Password Type: PasswordText / PasswordDigest
│ └── Timestamp: Include (validity 5 min)

Der generierte SOAP-Envelope enthält dann:

<soap:Envelope>
<soap:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>API_USER</wsse:Username>
<wsse:Password Type="PasswordText">...</wsse:Password>
<wsse:Nonce>...</wsse:Nonce>
<wsu:Created>2026-02-14T10:00:00Z</wsu:Created>
</wsse:UsernameToken>
<wsu:Timestamp>
<wsu:Created>2026-02-14T10:00:00Z</wsu:Created>
<wsu:Expires>2026-02-14T10:05:00Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soap:Header>
<soap:Body>...</soap:Body>
</soap:Envelope>

Best Practices

ThemaEmpfehlung
WSDL-VersionierungWSDL-Datei im Git-Repository versionieren
Proxy-RegenerierungBei WSDL-Änderungen Service Consumption Model neu generieren
FehlerbehandlungImmer SOAP Faults und System Faults unterscheiden
RetryNur bei transienten Fehlern, nicht bei SOAP Faults
TimeoutAngemessene Timeouts in Communication Arrangement setzen
LoggingAlle SOAP-Aufrufe für Debugging loggen
TestingMock-Services für Unit Tests verwenden
SecurityCredentials niemals im Code, immer in Communication System

Häufige Fehler und Lösungen

FehlerUrsacheLösung
CX_AI_SYSTEM_FAULTTechnischer FehlerNetzwerk prüfen, WSDL validieren
SOAP Fault: Invalid RequestUngültige DatenRequest-Struktur gegen WSDL prüfen
HTTP 401AuthentifizierungCredentials in Comm. System prüfen
HTTP 403AutorisierungBerechtigungen im Zielsystem prüfen
TimeoutLangsamer ServiceTimeout erhöhen, ggf. async verarbeiten
Certificate ErrorTLS-ProblemServer-Zertifikat in Trust Store

Weiterführende Themen