on 11-06-2012 4:02 PM
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
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
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
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
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
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
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
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,
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
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
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
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
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) {
}
});
},
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Please find code to get the file content if file is uploaded by Form
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I have the same question and I am looking forward someone could give some hints on this.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
83 | |
24 | |
12 | |
9 | |
7 | |
6 | |
5 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.