[英]Uploading file from Angular ng-file-upload to Play for Scala
[英]Scala Play Framework image upload with Angular ng-file-upload
我在前端使用Angular ng-file-upload
( https://github.com/danialfarid/ng-file-upload )管理文件上傳過程。
不幸的是,表單包含具有多個文件的復雜對象。 使用服務器端的MultipartFormData
( https://www.playframework.com/documentation/2.5.x/ScalaBodyParsers ),我已經成功分解了上傳的內容,並且可以從request.body
讀取它。
現在,令我驚訝的是,我沒有一個簡單的Json Objects
,而是一個奇怪地形成的數據類型,在ng-file-upload
網站上描述為:
(...)服務器實現期望使用.key或[key]格式的嵌套數據對象鍵。 示例:數據:{記錄:{名稱:'N',圖片:文件}}發送為:記錄[名稱]-> N,記錄[圖片]->文件
數據:{記錄:{名稱:'N',圖片:文件},對象關鍵字:'。k'}發送為:記錄名稱-> N,記錄圖片->文件
到目前為止,我已經設法使用DataPart
和FilePart
將所有數據轉換為通用的MultipartFormData.Part
類型:
val opts = body.dataParts.map {
case (key, values) => DataPart(key, values.head)
}
val parts = opts ++ body.files
因此,我現在有一個非常不幸的Iterable[Part]
:
0 = {MultipartFormData$DataPart@86271} "DataPart(arabic[active],false)"
1 = {MultipartFormData$DataPart@86273} "DataPart(english[active],true)"
2 = {MultipartFormData$DataPart@86277} "DataPart(english[url],2132132132)"
...
7 = {MultipartFormData$FilePart@76473} "FilePart(english[image],fb_icon_325x325.png,Some(image/png),TemporaryFile(/tmp/playtemp5909927824995768544/multipartBody8348573128070542611asTemporaryFile))"
每個對象name
包含其Json結構的key
及其相應的value
。 現在,我想將其解析為對象而不是key[level1][level2]
:
case class PcBanner(english: PcBanners, arabic: PcBanners, kurdish: PcBanners)
case class PcBanners(active: Boolean, url: Option[String], image: Option[String])`
我希望你有主意。
問題
我知道我可以嘗試解析name
字符串以使其適合對象,但是我相信中間還是有一個錯誤。 有沒有一種方法可以使用字段名稱作為參考來將此結構解析為對象? 播放功能有內置功能嗎?
感謝幫助!
正如我在標題中所述,我的情況是發送圖像 。 如您所料,我還將展示一個預覽以及當前保存在數據庫中的文件。
考慮到所有優點和缺點,我決定以兩種方式均以JSON格式發送所有數據。
這意味着圖像將以JSON結構進行編碼和發送。
盡管上述解決方案看起來非常方便,但實際上在實施過程中會產生新的問題。
對於這個錯誤的解決方案,我不會使用更深的含義,而是使用@danial建議:
沒有像這樣單獨發送文件
{file: file, otherData: JSON.stringify(myData)}
我的解決方案
如果有人想使用類似的方法來挖掘我的答案。 在前端,我決定使用ng-file-upload庫。 它具有結合到HTML組件ngf-select
與ngf-drop
這使得部件:
<div ngf-drop ngf-select
ng-model="image"
ngf-accept="'image/*'"
ngf-resize="{width: {{width}}, height: {{height}}, quality: 1.0, restoreExif: false}">
<img ng-show="!!image && !!image.$ngfName" ngf-src="image">
<img ng-show="(!image || !image.$ngfName)" ng-src="{{ imageUrl }}">
</div>
在上載標簽中,我放置了圖像預覽。 這可以完美地工作。 如果未選擇圖像,則使用保存在數據庫中的圖像。
數據和圖像不再共享模型。 上傳功能如下:
return Upload.upload({
url: url,
data: {file: images, data: angular.toJson(data)}
}).then(function (resp) {
console.log(resp);
}, function (error) {
console.log(error);
});
將以上所有內容放在一起,便得到了輸出數據對象:
{
"english":{
"active":true,
"url":"http://google.com"
},
"arabic":{
"active":true,
"url":"http://google.com"
},
"kurdish":{
"active":true,
"url":"http://google.com"
}
}
在服務器端,JSON與准備好的case類匹配,並使用內置的Jackson解析器進行解析,從而簡化了對象操作。 該圖像必須手動選擇:
val json = r.body.dataParts("data")
val jsValue = Json.parse(json.head)
val result = jsValue.validate(LocalizedBanner.dataModelFormat) // parse JSON
可以使用內置函數.file
從主體中提取文件:
val key = s"file[${lang.name}][${imageType.name}]"
body.file(key).map(mp => (mp.ref.file, imageType))
請享用!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.