Application Development and Automation Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
sanjay22
Discoverer
1,327

File uploads let you add file handling functionality to your applications inside the framework of SAP's Rapid Application Programming (RAP) methodology. This gives customers the ability to upload a variety of file formats, including photos, Excel spreadsheets, PDFs, and more.

SAP's Rapid Application Programming (RAP) architecture allows you to integrate file handling functionality into your applications through file uploads. Users can now upload a variety of file kinds, including PDFs, Excel spreadsheets, photos, and more.

OData streams are now supported by the RAP framework thanks to the most recent release of SAP BTP ABAP 2208. You may now make your RAP application capable of handling and maintaining Large Objects (LOBs).This feature enables media handling by giving end users the ability to upload external files in a variety of file formats, including PDF, XLSX, binary, and others.

In this Blog we will explore how to upload and handle Large Object such as PDF or Binary files without the need to extend the RAP application in BAS.

Large objects are modelled by means of the following fields: 

  • Attachment  
  • Mime type  
  • Filename 

The field Attachment contains the LOB itself in a RAWSTRING format and is technically bound to the field Mime type and Filename using semantics annotation.

Mime type represents the content type of the attachment uploaded and the values for the fields Mime type and Filename are derived from the field Attachment by the RAP framework based on the maintained CDS annotations. No attachment can exist without its mime type and vice versa.

For example, when a TEXT file is uploaded the Mime type field will be derived and populated with ‘APPLICATION/txt’.

Step 1 : Create the data element of raw string Datatype for the field that stores the file attachment in                      the Table.

sanjay22_1-1737095963931.png

Step 2 :  Creating the Database table using below fields.

sanjay22_2-1737096033031.png

Step 3 : Create the Interface view on Above Database table.

sanjay22_3-1737096079836.png

  • @Semantics.mimeType: true => Use the above annotations to Handle the field as Mime Type by  Internal Framework and to store the attached file which is usually large data.
  •  @Semantics.largeObject : { mime Type: 'mime type', file Name: 'filename', content Disposition Preference: #ATTACHMENT } => In this annotations we have to pass the mime type field name and the field which stores the file name.

Step 4 :  Create the Projection View on Interface View.

sanjay22_0-1737096789935.png

Step 5 : Create the meta data extension for the created consumption view.

sanjay22_1-1737097033139.png

Step 6 : create the behavior definition for Interface View and choose the Implementation type as UnmanagedFor Media handling it is mandatory to create the OData v4 and with Draft functionality.

sanjay22_0-1737097882486.png

sanjay22_1-1737098266763.png 

Draft table for the persistent Table.

Step 7 : Create the Implementation class for the behavior definition for CRUD operation.

 

CLASS lhc_zr_sm_t_file_hand DEFINITION INHERITING FROM cl_abap_behavior_handler.
  PRIVATE SECTION.

    METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
      IMPORTING keys REQUEST requested_authorizations FOR zr_sm_t_file_hand RESULT result.

    METHODS create FOR MODIFY
      IMPORTING entities FOR CREATE zr_sm_t_file_hand.

    METHODS update FOR MODIFY
      IMPORTING entities FOR UPDATE zr_sm_t_file_hand.

    METHODS delete FOR MODIFY
      IMPORTING keys FOR DELETE zr_sm_t_file_hand.

    METHODS read FOR READ
      IMPORTING keys FOR READ zr_sm_t_file_hand RESULT result.

    METHODS lock FOR LOCK
      IMPORTING keys FOR LOCK zr_sm_t_file_hand.

ENDCLASS.

CLASS lhc_zr_sm_t_file_hand IMPLEMENTATION.

  METHOD get_instance_authorizations.
  ENDMETHOD.

  METHOD create.

    zcl_sm_unmanaged_crud=>get_instance(  )->create(
      EXPORTING
        entities = entities
      CHANGING
        mapped   = mapped
        failed   = failed
        reported = reported
    ).

  ENDMETHOD.

  METHOD update.

  zcl_sm_unmanaged_crud=>get_instance(  )->update(
    EXPORTING
      entities = entities
    CHANGING
      mapped   = mapped
      failed   = failed
      reported = reported
  ).

  ENDMETHOD.

  METHOD delete.

    CALL METHOD zcl_sm_unmanaged_crud=>get_instance(  )->delete(
      EXPORTING
        keys     = keys
      CHANGING
        mapped   = mapped
        failed   = failed
        reported = reported
    ).

  ENDMETHOD.

  METHOD read.

    zcl_sm_unmanaged_crud=>get_instance(  )->read(
      EXPORTING
        keys     = keys
      CHANGING
        result   = result
        failed   = failed
        reported = reported
    ).

  ENDMETHOD.

  METHOD lock.
  ENDMETHOD.

ENDCLASS.

CLASS lsc_ZR_SM_T_FILE_HAND DEFINITION INHERITING FROM cl_abap_behavior_saver.
  PROTECTED SECTION.

    METHODS finalize REDEFINITION.

    METHODS check_before_save REDEFINITION.

    METHODS save REDEFINITION.

    METHODS cleanup REDEFINITION.

    METHODS cleanup_finalize REDEFINITION.

ENDCLASS.

CLASS lsc_ZR_SM_T_FILE_HAND IMPLEMENTATION.

  METHOD finalize.
  ENDMETHOD.

  METHOD check_before_save.
  ENDMETHOD.

  METHOD save.

    zcl_sm_unmanaged_crud=>get_instance(  )->save_data(
      CHANGING
        reported = reported
    ).

  ENDMETHOD.

  METHOD cleanup.
  ENDMETHOD.

  METHOD cleanup_finalize.
  ENDMETHOD.

ENDCLASS.

 

 

Step 8 : Create the API class for the Implementation class.

 

CLASS zcl_sm_unmanaged_crud DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    TYPES: tt_std_create     TYPE TABLE FOR CREATE zr_sm_t_file_hand,
           tt_std_update     TYPE TABLE FOR UPDATE zr_sm_t_file_hand,
           tt_mapped_early   TYPE RESPONSE FOR MAPPED EARLY zr_sm_t_file_hand,
           tt_failed_early   TYPE RESPONSE FOR FAILED EARLY zr_sm_t_file_hand,
           tt_reported_early TYPE RESPONSE FOR REPORTED EARLY zr_sm_t_file_hand,
           tt_mapped_late    TYPE RESPONSE FOR MAPPED LATE zr_sm_t_file_hand,
           tt_reported_late  TYPE RESPONSE FOR REPORTED LATE zr_sm_t_file_hand,
           tt_keys_read      TYPE TABLE FOR READ IMPORT zr_sm_t_file_hand,
           tt_keys_delete    TYPE TABLE FOR DELETE zr_sm_t_file_hand,
           tt_read_result    TYPE TABLE FOR READ RESULT zr_sm_t_file_hand.

    CLASS-METHODS get_instance RETURNING VALUE(ret_student) TYPE REF TO zcl_sm_unmanaged_crud.

    METHODS: create IMPORTING entities TYPE tt_std_create
                    CHANGING  mapped   TYPE tt_mapped_early
                              failed   TYPE tt_failed_early
                              reported TYPE tt_reported_early,

             read IMPORTING keys     TYPE tt_keys_read
                  CHANGING  result   TYPE tt_read_result
                            failed   TYPE tt_failed_early
                            reported TYPE tt_reported_early,

             update IMPORTING entities TYPE tt_std_update
                    CHANGING  mapped   TYPE tt_mapped_early
                              failed   TYPE tt_failed_early
                              reported TYPE tt_reported_early,

             delete IMPORTING keys     TYPE tt_keys_delete
                    CHANGING  mapped   TYPE tt_mapped_early
                              failed   TYPE tt_failed_early
                              reported TYPE tt_reported_early,

             save_data CHANGING reported TYPE tt_reported_late.

  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-DATA: go_instance TYPE REF TO zcl_sm_unmanaged_crud,
                gt_create   TYPE TABLE OF zsm_t_file_hand,
                gt_update   TYPE TABLE OF zsm_t_file_hand,
                gr_delete   TYPE RANGE OF zr_sm_t_file_hand-DocumentId,
                gs_file     TYPE zsm_t_file_hand.
ENDCLASS.



CLASS zcl_sm_unmanaged_crud IMPLEMENTATION.

  METHOD get_instance.

    ret_student = COND #( WHEN go_instance IS BOUND THEN go_instance
                          ELSE NEW #(  ) ).

  ENDMETHOD.

  METHOD create.

    gt_create = CORRESPONDING #( entities MAPPING FROM ENTITY ).

    LOOP AT entities ASSIGNING FIELD-SYMBOL(<lfs_entities>).

      IF gt_create IS NOT INITIAL.

        gt_create[ 1 ]-client = sy-mandt.
        gt_create[ 1 ]-last_changed_by = sy-uname.
        GET TIME STAMP FIELD DATA(lv_timestamp).
        gt_create[ 1 ]-last_changed_at = lv_timestamp.

        mapped-zr_sm_t_file_hand = VALUE #( ( %cid = <lfs_entities>-%cid
                                              %key = <lfs_entities>-%key
                                              %is_draft = <lfs_entities>-%is_draft ) ).
      ENDIF.


    ENDLOOP.
  ENDMETHOD.

  METHOD save_data.

    IF gt_create IS NOT INITIAL.

      INSERT zsm_t_file_hand FROM TABLE _create.
      CLEAR gt_create[].

    ELSEIF gt_update IS NOT INITIAL.

      UPDATE zsm_t_file_hand FROM TABLE _update.
      CLEAR gt_update[].

    ELSEIF gr_delete IS NOT INITIAL.

      DELETE FROM zsm_t_file_hand WHERE document_id IN _delete.
      CLEAR gr_delete[].

    ENDIF.

  ENDMETHOD.

  METHOD update.

    DATA : lt_update_x TYPE STANDARD TABLE OF zsm_ts_boolean,
           lt_update   TYPE STANDARD TABLE OF zsm_t_file_hand.

    lt_update = CORRESPONDING #( entities MAPPING FROM ENTITY ).
    lt_update_x = CORRESPONDING #( entities MAPPING FROM ENTITY USING CONTROL ).

    IF lt_update IS NOT INITIAL.
*
      SELECT * FROM zsm_t_file_hand FOR ALL ENTRIES IN _update
      WHERE document_id = _update-document_id
      INTO TABLE (lt_result_old).

    ENDIF.
    GET TIME STAMP FIELD DATA(lv_timestamp).
    gt_update = VALUE #(

                 FOR x = 1 WHILE x LE lines( lt_update )

                 LET ls_control_flag = VALUE #( lt_update_x[ x ] OPTIONAL )
                     ls_new   = VALUE #( lt_update[ x ] OPTIONAL )
                     ls_old   = VALUE #( lt_result_old[ document_id = ls_new-document_id ] OPTIONAL )

                 IN
                 (
                    client     = sy-mandt
                    document_id = COND #( WHEN ls_control_flag-document_id IS INITIAL
                                          THEN ls_old-document_id )
                    filename = COND #( WHEN ls_control_flag-filename IS NOT INITIAL
                                      THEN ls_new-filename ELSE ls_old-filename )
                   attachment = COND #( WHEN ls_control_flag-attachment IS NOT INITIAL
                                      THEN ls_new-attachment ELSE ls_old-attachment )
                   mimetype = COND #( WHEN ls_control_flag-mimetype IS NOT INITIAL
                                      THEN ls_new-mimetype ELSE ls_old-mimetype )
                   created_at = COND #( WHEN ls_control_flag-created_at IS INITIAL
                                      THEN ls_old-created_at )
                   created_by = COND #( WHEN ls_control_flag-created_by IS INITIAL
                                      THEN ls_old-created_by )
                   last_changed_at = COND #( WHEN ls_control_flag-last_changed_at IS INITIAL
                                      THEN lv_timestamp )
                   last_changed_by = COND #( WHEN ls_control_flag-last_changed_by IS INITIAL
                                      THEN sy-uname )

                  ) ).


  ENDMETHOD.

  METHOD read.

    SELECT * FROM zsm_t_file_hand FOR ALL ENTRIES IN 
    WHERE document_id = -DocumentId
    INTO TABLE (lt_result).

    result = CORRESPONDING #( lt_result MAPPING TO ENTITY ).

  ENDMETHOD.

  METHOD delete.

     DATA: lt_delete TYPE STANDARD TABLE OF zsm_t_file_hand.

           lt_delete = CORRESPONDING #( keys MAPPING FROM ENTITY ).

           gr_delete = VALUE #(

                             FOR ls_delete IN lt_delete
                             sign = 'I' option = 'EQ' ( low = ls_delete-document_id )
                              ).

  ENDMETHOD.

ENDCLASS.

 

 

Step 7 : create the behavior definition for the Projection View.

sanjay22_0-1737098826915.png

Step 8 : Create the Service definition for the consumption view.

sanjay22_1-1737098906787.png

Step 9 : Create the Service Binding for Created Service definition and Choose the Binding type as OData V4 ,activate and publish the service.

sanjay22_2-1737098953938.png

Preview the Application and click on create to upload the file.

sanjay22_0-1737099647005.png

Click on upload icon near to the attachment field, select the file, file name will be auto filled and fill the Mime type manually.

sanjay22_1-1737099684894.png

sanjay22_3-1737099810705.png

 

sanjay22_4-1737099820369.png

 

 

3 Comments
DiegoValdivia
Active Participant

RAP doesn't mean "Rapid Application Programming" but "RESTful Application Programming"

sanjay22
Discoverer

Hi @DiegoValdivia it's a genuine mistake and thank you for letting me know

Sunil_kumar2
Discoverer
0 Kudos

Hi @sasanjay22


I'm facing problem.

1. there is difference with your.

No any upload input appears here. 

Sunil_kumar2_1-1742292537957.png

2. error while create 

Sunil_kumar2_2-1742292537958.png

Any guide?

Sunil_kumar2_3-1742292537958.png

 

 

Labels in this area