Skip to Content
Technical Articles
Author's profile photo Marat Bareev

SAP PO: Using attachments in REST Receiver adapter

Recently I has been working on synchronous integration scenario which involves sending JSON with some files (usually PDFs) attached using REST adapter. Attachments are accepted by the receiver through HTTP POST request with multipart/form-data encoding. Attachment filenames must be preserved for receiver system since they are stored and displayed to end-user. Response contains JSON with operation status and error log (if any). Sender system is SAP S/4HANA with ABAP-proxy generated based on message type defined in SAP PO.

The challenge was to fulfill the task using only standard SAP PO REST adapter without use of any adapter modules and custom JAVA mapping to build the request body.

Here are my findings.

SAP PO Configuration

I am using SAP PO 7.50 SP24 so if you have earlier releases your milage may vary.

REST Receiver communication channel for receiving system is created. In order to support sending and receiving JSON format you need to select appropriate “Data Format” = JSON for Request and Response configuration sections. Also “Support attachments” must be selected for channel in order to push any attachments to the receiver. Multipart content type “multipart/form-data” is also selected as per receiver system requirement.

Other communication channel properties are not relevant to this blog entry but are not related to attachments being sent.

REST%20Receiver%20Communication%20Channel

REST Receiver Communication Channel

Operation Mapping and Message Mapping work only on main message part, no attachments. No adjustments were made to Sender Communication Channel (SOAP-XI Channel) or ICo in order to support attachments.

Code on ABAP side (SAP S/4HANA)

If you follow official guides and articles when dealing with attachments you will get an attachment with internally generated name (specified as Content-ID in XI). This autogenerated name is then passed to the receiver which is not acceptable for this integration scenario.

Message%20attachments%20in%20Message%20Monitor

Message attachments in Message Monitor

In order to fix the issue attachment needs to be added to ABAP-proxy instance in a specific way which exposes “Content-Disposition” attribute of the payload. Below is code required to create attachment object, set up attachment headers correctly and send attachment alongside main payload.

Filename may include non-Latin characters. If this is the case, filename must be encoded according to RFC 2047 and RFC5987, where UTF-8 is used as target encoding.

DATA lv_filename TYPE string " filename to be sent
DATA lv_xstring TYPE xstring " binary content of the file to be sent

  " generated ABAP-proxy
  DATA(lo_proxy) = NEW zco_create_document_request_ou( ). 

  DATA :
    " support for XI attachment protocol
    lo_attch_protocol TYPE REF TO if_wsprotocol_attachments, 
    " request message type
    ls_request        TYPE zcreate_document_request, 
    " response message type
    ls_response       TYPE zcreate_document_confirmation. 

  " encodes filename for XI
  " see details below
  DATA: lv_encoded_filename TYPE string.
  PERFORM encode_rfc2047_rfc5987 USING lv_filename CHANGING lv_encoded_filename.

  " get MIME type based on filename (extension).
  " if extension is missing or unknown -- generic application/octet-stream will be returned.
  DATA(lv_content_type) = ||.
  CALL FUNCTION 'SKWF_MIMETYPE_OF_FILE_GET'
    EXPORTING
      filename = p_name              " File Name
    IMPORTING
      mimetype = lv_content_type. " MIME Type

  " create attachment object
  DATA(lo_payload) = NEW cl_xms_payload( ).
  lo_payload->if_xms_payload~setpayloadtype( 'A' ). " ApplicationAttachment
  lo_payload->if_xms_payload~setbinarycontent(
                                  data = lv_xstring       " binary content
                                  type = lv_content_type  " MIME content type
                                  ). "
  lo_payload->if_xms_payload~set_disposition( |form-data; name="filename"; { lv_encoded_filename }| ).
  lo_payload->if_xms_payload~setdocumentname( p_name ). " visible in SXI_MONITOR

  " add attachment object to ABAP-proxy instance
  DATA(lo_attachment) = NEW cl_ai_attachment( p_from_type = 'B' ).
  lo_attachment->set_payload( lo_payload ).
  lo_attch_protocol ?= lo_proxy->get_protocol( if_wsprotocol=>attachments ).
  lo_attch_protocol->set_attachments( VALUE #( ( lo_attachment ) ) ).

  " here <ls_request> must be filled as per functional specification
" skipped as non-essential

  " call ABAP-proxy
  lo_proxy->create_document_request_out_sy(
    EXPORTING
      output = ls_request
    IMPORTING
      input  = ls_response ).

**********************************************************************

FORM encode_rfc2047_rfc5987 USING i_filename
                  CHANGING i_encoded_filename TYPE string.

  " encodes filename according to RFC 2047 and RFC 5987
  " uses UTF-8 encoding and BASE64 encoding
  " returns correct header for Content-Disposition MIME field
  " FORM must be used if filename may include symbols outside ISO-8859-1 (Latin 1) codepage

  DATA(lv_filename_to_encode) = CONV string( i_filename ).
  DATA(lv_base64_filename) = cl_http_utility=>if_http_utility~encode_x_base64(
                                          cl_http_utility=>if_http_utility~encode_utf8(
                                                lv_filename_to_encode
                                                )
                                              ).
  DATA(lv_rfc5987_filename) = escape( val = lv_filename_to_encode format = cl_abap_format=>e_xss_url ).

  i_encoded_filename = |filename="=?utf-8?B?{ lv_base64_filename }?="; filename*=UTF-8''{ lv_rfc5987_filename }|.

ENDFORM.


Demonstration

For demonstration purposes I have sent a message which contains main payload (to be converted to JSON) and one PDF attachment. Below are screenshots from SXI_MONITOR showing example message with attachment:

SXI_MONITOR%20message%20view

SXI_MONITOR message view

SOAP%20Manifest

SOAP Manifest

NWA Message Monitor showing attachment

If you open message in Message Monitor — attachment will be listed with correct name.

NWA%20Message%20Monitor%20showing%20attachment

Message Monitor — attachment view

Below is HTTP dump for the request to the receiving system. Filename is transmitted in UTF-8 encoding but decoded from RFC 2047 encoding during HTTP call.

Message%20Monitor%20--%20attachment%20view

Setting Content-Disposition for main payload (OPTIONAL)

Receiving system requested that main payload should have a specific constant value in its Content-Disposition header instead of automatically generated one. Easiest way to archive it is to modify this field on Receiver Channel side using standard adapter module MessageTransformBean.

In order to replace Content-Disposition for main payload, add module AF_Modules/MessageTransformBean and specify parameter Transform.ContentDisposition with requested value (for example — form-data; name=”request”).

Adapter%20Module%20configuration

Adapter Module configuration

Content-Disposition for main payload is successfully replaced with a constant:

UTF-8 support

Below is an example message showing full UTF-8 support. In this example file has Cyrillic characters in its name:

SXI_MONITOR%20message%20view

SXI_MONITOR message view

Message%20manifest

Message manifest

NWA%20Message%20Versions%20--%20Attachment%20view

NWA Message Monitor — Attachment view

NOTE: this screen is broken — it will not show UTF-8 encoded text. Screen interprets this field as Latin-1 codepage so it shows up broken. This only affects the display, internally filename is interpreted correctly. Once SAP releases a fix for this issue, I will update the article.

NWA%20Message%20Monitor%20--%20Attachment%20view

NWA Message Versions — Attachment view

Filename is passed by REST adapter to the receiving system as UTF-8 string and as RFC 5987-encoded one:

Conclusion

Described method works great with REST Receiver adapter and should work the same way (albeit with some caveats) with all receiver adapters which natively support attachments — such as SOAP, File and Mail adapters.

Thank you for your attention!

Hope this article will prove useful in your integration adventures!

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.