cancel
Showing results for 
Search instead for 
Did you mean: 

File Attachment using gateway

jibin_joy
Contributor
0 Kudos

Hi Everyone,

     New scenario: uploading and downloading file using SAP Netweaver Gateway .

Dont know how to solve this  one .

I like to have ur valuable suggestion and Advice for this requirement.

Thanks in Advance,

Regards,

Jibin JOy

Accepted Solutions (1)

Accepted Solutions (1)

former_member182048
Active Contributor
0 Kudos

Hi Jibin / Jessie

TLDR The answer depends on the requirement.  There are a few ways I can think of to achieve Uploading and Downloading files with Gateway services. The most efficient way is to provide URL links to the file content, then have separate client calls stream the data to and from the server via the Gateway service or maintain the data by methods independent of the Gateway service .

The OData protocol enables you to define data feeds that also make binary large object (BLOB) data, such as photos, videos, and documents available to client applications that consume the OData feeds. For performance reasons it is not good practice to return the BLOB's in the feed themselves, rather call the Binary Data, known as a Media Resource separately via a Media Link Entry present in the feed.

eg.

<content type="image/jpeg" src="EmployeePhoto(4)/$value" />

<link rel="edit-media" title="EmployeePhoto" href="EmployeePhoto(4)/$value" />

or

<content type="image/jpeg" src="http://www.linkedin.com/profilephotos/xyz.jpg" />

Example of using Media Links to retrieve Workflow attachments. Workflow Services -> Media Links - see

DPC: /IWWRK/CL_MGW_RT_WORKFLOW

MPC: /IWWRK/CL_MGW_MED_WORKFLOW

If you have access to the the Electronic Medical Record Gateway services you can see both how to use both Media Links and Binary fields in the feed

/MEMR/CL_ET_ATTACHMENT_HANDLER

/MEMR/CL_ET_DOCUMENT_HANDLER

To support streaming in Gateway services,the DPC has the following methods :

/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_STREAM

/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM

/IWBEP/IF_MGW_APPL_SRV_RUNTIME~UPDATE_ENTITY

/IWBEP/IF_MGW_APPL_SRV_RUNTIME~DELETE_STREAM

The first half of this document explains how it should work OData support for streams

The only full CRUD example i could find is

/IWBEP/CL_MGW_RT_SFLIGHT local class LCL_CARRIER->Create/Update/Delete_Stream, however this code doesn't seem active or recent.

Hope it helps.

Cheers

John P

jibin_joy
Contributor
0 Kudos

Hi John,

      How /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM method is invoked I mean can u provide me the sample url to invoke this method.

Thanks,

Jibin Joy

former_member182048
Active Contributor
0 Kudos

Hi Jibin

As an example of how to call GET_STREAM for a carrier

call the following to get the entity

http://server:port/sap/opu/odata/IWFND/RMTSAMPLEFLIGHT/CarrierCollection('AA')

in  the payload you will see a couple of links

<link href="CarrierCollection('AA')/$value" rel="edit-media" type="image/gif" />

<content type="image/gif" src="CarrierCollection('AA')/$value" />

if you do a GET

/sap/opu/odata/IWFND/RMTSAMPLEFLIGHT/CarrierCollection('AA')/$value

set header accept = image/gif

you should see that GET_STREAM is called.

likewise if you do a PUT on

/sap/opu/odata/IWFND/RMTSAMPLEFLIGHT/CarrierCollection('AA')/$value

set header content-type  = image/gif

you should be able to update the image calling UPDATE_STREAM

**first you need to setup a default virus profile

UPDATE:

Transaction /IWFND/VIRUS_SCAN here you can set or turn off Virus Scan

Also attached screen shot for CREATE_STREAM for Carrier, need to call the collection with the right headers and a slug

Cheers

JSP

jibin_joy
Contributor
0 Kudos

Hi John,

  It was very helpful info . It's working properly .

But i am facing some pblm during SEGW class generation .

Currently using SAP Netwear Gateway SP5

based on the document  http://help.sap.com/saphelp_gateway20sp04/helpdata/en/67/d2c38221984d8eb46b8a8d983407b9/content.htm

for media type setting 

* setting a data object as media type means that it gets a special semantic by having a url and allows streaming etc.

  lo_data_object->set_is_media( ).

for mime type information setting

* must be set when data object is a media type to mark the property which represents the mime type information

  lo_property->set_fc_target_path( iv_keep_in_content = abap_true iv_fc_target_path = gcs_fc_target_path - content/@type ).

but during generating run-time object  the above code is not generate.

for running i manually added above code in generated class   .

I need ur valuable suggestion to resolve this pblm.

Thanks in advance

Regards,

Jibin Joy

former_member182048
Active Contributor
0 Kudos

Hi Jibin

Thanks for the link to the Media Link help document, I never saw that before, could have save me a lot of time attempting to write something similar.

I am using a SP4 system and the Gateway builder doesn't have some of the features shown in your screenshots. Given you are on SP5 suggests you are a customer and entitled to raise an OSS note, you could either live the workaround or raise a Note.

Cheers

John P

jibin_joy
Contributor
0 Kudos

Hi John,

           Do u know how to set the filename since wht were file we are downloading will have same name "$value" but i want my file name like doc1.doc so that it will be more flexible to open that downloaded files

Thanks in Advance,

Regards,

Jibin Joy

jibin_joy
Contributor
0 Kudos

Hi John,

For setting up the file name .

we have to manually add one header content

  

   DATA ls_temp TYPE LINE OF  tihttpnvp.

        ls_temp-name = 'Content-Disposition'.

        ls_temp-value = 'inline; filename="doc2.doc"'.

   APPEND ls_temp TO ct_headers.

Plz Ref http://www.ietf.org/rfc/rfc1806.txt

Regards,

Jibin Joy

former_member182048
Active Contributor
0 Kudos

thanks will try.

jibin_joy
Contributor
0 Kudos

Hi John,

For ur Future ref..........

Based on my observation the following might be a problem for streaming and i dont know whether it is right or not . just try it whenever got  time.

1. Create Stream

Request Body :

------WebKitFormBoundary2BKGSHLTKayEh8qt

Content-Disposition: form-data; name="fileUpload"; filename="text1.txt"

Content-Type: text/plain

-----file stream data ----

------WebKitFormBoundary2BKGSHLTKayEh8qt--

In create stream method, file stream data is not properly fetched ....

If u observe media resource variable in method , will contain all the data from  top to bottom (including ------WebKitFormBoundary2BKGSHLTKayEh8qt ......... ) as shown above .

and dont know show to fetch the uploaded file name also.

2. Update Stream

Throws an error for update stream

Error :

" The server is refusing to process the request because the entity has a unsupported format "

Class   : /IWCOR/CL_DS_PROC_DISPATCHER

Method  : PROCESS_ENTITY

Content :

      .

      .

      .

      .

      .

      .

  validate_content_type(

           it_supported_format = lt_supported_format
           iv_content_type = io_request_entity->get_header_field( if_http_header_fields=>content_type )  ).

      .

      .

      .

      .

      .

io_request_entity>get_header_field( if_http_header_fields=>content_type )

The above code returns "multipart/form-data"


and lt_supported_format contain following value

application/atom+xml

application/atom+xml;type=entry

application/json

application/json;odata=verbose

application/xml

application/json

And validate_content_type method check Request Header ("multipart/form-data") in lt_supported_format.

if not found above error is thrown.

Regards,

Jibin Joy



former_member182048
Active Contributor
0 Kudos

Hi Jibin

Just to clarify what the issue is.

You are using a browser and trying to upload a file as a stream using an input form

i'm guess something like

<form name="form1" method="post" action="/gatewayservice">

     <input type="file" name= "fileUpload">

You are expecting Content-Type: text/plain to be sent

but the browser is wrapping your file in a Content-Type: multipart/form-data; and Gateway doesn't support this Content-Type

You are wanting to know how to send only Content-Type: text/plain from the browser.

I guess you could try changing the enctype of the form or better yet use the Filereader API to get the BLOB and then do an XHR to the gateway service.  See http://www.html5rocks.com/en/tutorials/file/dndfiles/ should give you some ideas of what is possible using webkit.

Cheers

JSP


jibin_joy
Contributor
0 Kudos

Hi John,

    

My scenario is simple trying to uploading any file it can be pdf , image or just a text.    

<form action="XXXXXX/XXX/XXXX/Customers"  method="post" enctype="multipart/form-data">

<input type='file' name='fileupload' />

</form>

this one is parsing fine but we have to add one more header X-Requested-With=XMLHttpRequest until then it will throw an error. but dont know how to set header during form submit . so we have to introduce one more object in between like servlet which will add header and pass to gateway.

For testing purpose i am using chrome rest client tool as u mentioned in past post .

     Based on my observation the browser is wrapping  file in a Content-Type: multipart/form-data and it support also but it is not parsing the file stream properly, as it does for multipart/mixed ( it fetch each request from batch request ) .

Hope i am clear with my  scenario .

Regards,

Jibin Joy

Former Member
0 Kudos

Hi Jibin,

Are you able to read the attachment as per the link,

http://help.sap.com/saphelp_gateway20sp04/helpdata/en/67/d2c38221984d8eb46b8a8d98

1. I am trying to read a pic from the application server as in this document.

2. I have created a entity type with few fields for emp details and one more field for Mime Type, like yours.


3.And while mapping a data source, I have mapped except mime,as we are coding in EXT class , what should i map here.

4.I am getting "Property 'mimeType' of Data Object 'EmployeeData' has no type assigned." error. Please let me know how you proceeded with next steps.

Thanks and Regards,



jibin_joy
Contributor
0 Kudos

Hi Peter Dinesh ,

  still now i didn't tested File attachment using RFC ..... for time being create temp attribute in RFC FM then map to that attribute .

and in  create , update or  get stream we can u mention actual mine type

Regards,

Jibin Joy

Former Member
0 Kudos

Hello John,

I want to upload a file like PDF or DOC from ui5 to backend, using oData.

I created a gateway service.

I know that I must redefine create_stream method, but I don't know how to do that.

Do you have an example, how to write this method in abap?

Thank you,

Mari

jibin_joy
Contributor
0 Kudos

Hi ,

Can u Refer :

Regards,

Jibin Joy

former_member184739
Contributor
0 Kudos

Hello Marinela,

I am not sure how to do this in SAPUI5 but Its pretty much easy if you can do this with pure HTML5.

Please use the below code snippet and let me know if you face any issues.

HTML code:

<!DOCTYPE html>

<html>

  <head>

  <script src="jquery-1.8.2.min.js" type="text/javascript" > </script>

    <script type="text/javascript">

    function rundCode() {

        var file = document.getElementById('test').files[0];

        if (file) {

            UploadMe(file);

        }

    }   

   

    function UploadMe(readFile) {

        var reader = new FileReader();

        reader.readAsArrayBuffer(readFile); //array buffer

        reader.onprogress = updateProgress;

        reader.onload = loaded;

        reader.onerror = errorHandler;

    }

  

    function loaded(evt) {

       

        var fileString = evt.target.result;

            $.ajaxSetup({

                      cache: false

                  });

                      

   //Get CSRF token using AJAX..i have just hard coded for easy understanding...        

   var token1 = "0Zf3eVblC5oZcXmRRRRuZw=="          

           $.ajax({

               url: "https://test.com:8080/sap/opu/odata/sap/Z_S_TEST_FILE/Upload_File/",

               type: "POST",

               contentType: "application/json",

               processData: false,                           

               data: fileString,

                dataType: "text",

               headers: {

                   "x-csrf-token" : token1,

                   "Authorization" : "Basic cnRoYW5DDDDD",

                   "slug": "Test_File"

               },

               success: function (response) {

            

                           }    

                     });                                                                                              

        }

    

    function errorHandler(evt) {

        if (evt.target.error.name == "NotReadableError") {

            // The file could not be read.

        }

    }

    function updateProgress(evt) {

    }

  

    </script>

  </head>

  <body>

    <input type="file" id="test"  class="AlltextAccount"  />

      <input type="button" value="upload" onclick="rundCode()" />

  </body>

</html>

Backend:

You can implement media links as suggsted by Jibin..

Regards

Prabaharan

Former Member
0 Kudos

Hello Jibin Joy,

I did your example 'How to Upload and Download Files Using SAP NW Gateway SP06'.

I try to upload a photo in backend, with test transaction for gateway service , but I have an error.

I attach the error.

Can you help me with that?

Thank you,

Mari

SyambabuAllu
Contributor
0 Kudos

Hi Marinela,

you missed the Entity Set name in URI level add entity set name in URI and try.

/sap/opu/odata/sap/ZUPLOAD_SRV/FileSet

Thanks,

Syam

Former Member
0 Kudos

Hello again,

I write entity set name which is /upload, but now I get another error.:(

Can you help me again please?

Thank you,

Marinela

SyambabuAllu
Contributor
0 Kudos

Hi,

your mentioned entity set name after "/" not required that in URI and also add the slug value and add the file in header level then try it.

Like given below

Thanks,

Syam

Former Member
0 Kudos

Hello Jibin,

Have you found a solution to the CREATE_STREAM issue where ----WebKitFormBoundary is included in the body of the request.  I am facing the same issue and not sure how to best strip that off so I can get binary data only for the image.

Thanks,

Rutul

Former Member
0 Kudos

Hello Jibin,

I am not sure if you found any solution for the issue where request body includes the WebKitForm in addition to the actual content of the file and that creates and issue in CREATE STREAM method.  Here is what I did to solve the issue:

Our scenario was to send a pic from a device.

1.  In the device, we took the image binary data and converted it to BASE64 format

2.  Passed the BASE64 data as RAW data instead of file attachment

3.  In CREATE STREAM method, we took the BASE64 data and decoded using standard FM

4.  Save the data as-is with .png extension to shared folder location.

Thanks,

Rutul Thakkar

jibin_joy
Contributor
0 Kudos

Hi Rutul ,

  This Problem has been Solved except for IE8 and IE9 Browser .

Regards,

Jibin Joy

Former Member
0 Kudos

Hello Jibin,

Could you please share your method of solving the issue?  I would be interested to know if there is another solution.

Thank you,

Rutul

Former Member
0 Kudos

Hi Rahul,

Can you please provide code snippet on how you achieved attachment ? We have a very similar requirement and looking forward for your solution.

1. How did you convert the code in binary format from SAPUI5 ?

2. How did you decode the code in base64 format and displayed as attachment to user ?

Thanks,
Vinit Pugaliya

Former Member
0 Kudos

Hello Vinit,

We did not have a SAPUI5 app.  Our app UI was built on iOS platform using X-Code.  The image data was converted into BASE64 and then passed as raw data in http request.  On SAP side, I did following:

1.  use FM  SCMS_XSTRING_TO_BINARY to convert the XSTRING to Binary

2.  use FM  SCMS_BINARY_TO_STRING to convert the binary into a string

3.  use FM  SSFC_BASE64_DECODE to decode the String in BASE64

4.  Save the data as-is as a file with .png extension on application server.

I hope this helps.

Thanks,

Rutul

Answers (6)

Answers (6)

raphaelbertani
Explorer

i resolved webkitformboundary problem putting a Ajax requisition and send the file object of ui5 in the event handleUploadComplete

 
                handleUploadComplete: function (oEvent) {
 
                    var oCremer = this.byId(oEvent.getParameter("id"));

                    $.ajax({
                        url: '-hide url-/GW_UPLOADER_SRV/uploadSet',
                        type: 'POST',
                        data: oCremer.FUEl.files[0],
                        contentType: false,
                        processData: false,
                        success: function (response) {
                        },
                        error: function (response, x) {
                        }
                    });


                },
0 Kudos

Hi john.patterson3

https://answers.sap.com/questions/13885261/downloaded-file-not-working-with-uploadset-sapui5.html

this is my get_stream. File downloads with 1 KB but corrupted.

Could you please advise on what might be going wrong?

  METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.

DATA ls_lheader TYPE ihttpnvp.

DATA : ls_media TYPE zdtt_insp_media.
DATA(lt_keys) = io_tech_request_context->get_keys( ).
DATA(lv_inspid) = VALUE #( lt_keys[ name = 'INSP_ID' ]-value OPTIONAL ).

DATA(lv_filename) = VALUE #( lt_keys[ name = 'FILENAME' ]-value OPTIONAL ).

ls_lheader-name = 'Content-Disposition'.
* ls_lheader-value = 'outline; filename="Mobile.pdf";'.
ls_lheader-value = |outline; filename={ lv_filename };|.
set_header( is_header = ls_lheader ).

IF lv_inspid IS NOT INITIAL AND lv_filename IS NOT INITIAL.
SELECT SINGLE FROM zdtt_insp_media
FIELDS insp_id, filename, cr_date,cr_time,value, mimetype
WHERE insp_id = @lv_inspid
AND filename = @lv_filename
INTO ( @ls_media-insp_id,@ls_media-filename,@ls_media-cr_date,@ls_media-cr_time,@ls_media-value, @ls_media-mimetype ).
IF sy-subrc EQ 0.
copy_data_to_ref( EXPORTING is_data = ls_media
CHANGING cr_data = er_stream ).
ENDIF.
ENDIF.
ENDMETHOD.
jibin_joy
Contributor
0 Kudos

Please find code to get the file content if file is uploaded by Form

thorsten_rams
Explorer
0 Kudos

This was exactly what I needed. It works perfectly! Thanks for the code.

We are getting the file from the frontend application via put REST service and were not able to open it after storing it ("file corrupt"). After removing the WebKitFormBoundary using this function module it works!

Former Member
0 Kudos

Hi Jibin,

Did you find a solution to your problem? I am facing the exact issue with the file surrounded by webkitformboundary when it is sent to the CREATE_STREAM method. The browser is IE8, so not much can be done here.

Regards

Neha

jibin_joy
Contributor
0 Kudos

Hi Neha,

  Can i know which  Service Package ur using .. If possible can u post ur UI Code in my mail ID .

Regards,

Jibin Joy

Former Member
0 Kudos

Hi Jibin,

NW 7.31 SP06. Could you send your email id? Thanks!

Best Regards

Neha

jibin_joy
Contributor
0 Kudos

Hi ,

  u can find it in my profile information...

Regards,

Jibin Joy

Former Member
0 Kudos

Hi Neha,

Did you find a solution on how to remove the webkitformboundary?  I am facing the same issue and would appreciate your help.

Thanks,

Rutul

Former Member
0 Kudos

Dear Friends,

I am facing a scenario wherein for a header(1st Entity) I need to upload multiple attachments(2nd Entity).

I have established an association and navigation between 2 entities. I understand that GET_STREAM/CREATE_STREAM are called based on operation via HTTP.

My issues is, how can I call the CREATE_STREAM or GET_STREAM multiple times for an entity ?.

Regards,

Venkat

Former Member
0 Kudos

I have the same question and I am looking forward someone could give some hints on this.