2013-08-07 221 views
1

我已經建立了採用Delphi XE2和我一個的DataSnap REST服務器已經添加了服務器方法通過T流上傳文件:上傳文件的DataSnap REST服務器

function TServerMethods.updateUploadFile(sFilename: string; UploadStream: TStream): string; 

我希望能夠調用這來自許多不同的客戶端(Android,iOS等),我一直在使用Postman(Chrome插件)等各種REST客戶端來測試該方法。但是到目前爲止,我無法讓它接受HTTP POST主體的內容。每當我發送POST命令我總是得到如下回應:

{"error":"Message content is not a valid JSON value."} 

我已經使用各種不同的「內容類型」設置,但似乎沒有任何工作嘗試。看起來好像DataSnap堅持的內容是JSON?我試過將一些有效的JSON粘貼到內容區域,但這也給出了相同的錯誤響應。

是否有人成功使用TStream作爲DataSnap服務器方法的輸入參數?我應該以另一種方式去做嗎?我已經使用TStream作爲多次下載文件的輸出參數,它運行良好,這是我第一次嘗試上傳。

UPDATE

我做了一個快速的Delphi DataSnap客戶機來測試uploadFile服務器方法而這一切的偉大工程。然後,我使用Fiddler來檢查Delphi客戶端用來在內容主體中發送TStream的POST命令,並且發現它是一個整數(字節)的JSON數組,例如[37,80,68,70,45,49,46,51,13,10]。所以我可以看到我可以在POSTing之前修改我的Android/iOS客戶端以將二進制數據轉換爲這種字節數組格式,但這是我無法做到的開銷。如果當TStream是一個返回參數時,DataSnap將流入原始二進制數據,爲什麼它不能將原始二進制數據流作爲輸入參數?

回答

3

似乎在POST命令中向請求主體添加內容數據時,DataSnap服務器堅持這個數據總是JSON。這就是爲什麼當使用TStream作爲輸入參數時,流數據被Delphi DataSnap客戶端轉換爲整數(字節)的JSON數組。這種格式的效率非常低,因爲每字節高達3位數,加上逗號,上傳數據的大小可以增長4倍。

因此,我所做的只是編碼要在Base64中上傳的數據。我的服務器方法現在看起來像這樣:

function TServerMethods.updateUploadFile(sFilename: string; Base64Data: TJSONObject): string; 

注意我正在將T64對象中的Base64字符串包裝起來。這是因爲如果你只是指定一個字符串類型,Delphi DataSnap客戶端將用GET調用該方法,並嘗試將整個Base64字符串放在URL路徑中,導致「連接關閉正常」錯誤。使用TJSONObject強制DataSnap使用POST並將數據放入內容主體中。傳遞的JSON對象是一對對象:

{"UploadedData":"JVBERi0xLjMNCiXi48B5SiWGTK3PaY.........."} 

這樣,上傳的數據大小更小,傳輸速度更快。我仍然希望能夠在內容主體中傳輸原始數據,但DataSnap不允許這樣做。