0

フロントエンドでAngular ng-file-uploadhttps://github.com/danialfarid/ng-file-upload)を使用してファイルアップロードプロセスを管理しています。Scala Play Framework Anggular ng-file-uploadを使用した画像アップロード

残念ながら、フォームには複数のファイルを含む複雑なオブジェクトが含まれています。サーバー側のMultipartFormDatahttps://www.playframework.com/documentation/2.5.x/ScalaBodyParsers)を使用すると、アップロードされたコンテンツが正常に分解され、request.bodyから読み取ることができます。中にネストされたデータオブジェクトのキーを期待し

(...)サーバの実装:

さて、私の驚きに、私はJson Objectsシンプルではなく、むしろ妙に形成されたデータ型を持っていない、としてng-file-uploadウェブサイト上で説明しました.keyまたは[key]形式。 例:data:{rec:{name: 'N'、pic:file}}:rec [name] - > N、rec [pic] - >ファイル
data:{rec:{name: 'N 'PIC:ファイル}、objectKey:' として送られた.K '}:rec.name - > N、rec.pic - >ファイル

は、これまでのところ私は、共通のMultipartFormData.Partにすべてのデータを持って管理していますタイプ、このようDataPartFilePart使用:

だから私は今、非常に不幸な Iterable[Part]が残っています
val opts = body.dataParts.map { 
    case (key, values) => DataPart(key, values.head) 
} 

val parts = opts ++ body.files 

0 = {[email protected]} "DataPart(arabic[active],false)" 
1 = {[email protected]} "DataPart(english[active],true)" 
2 = {[email protected]} "DataPart(english[url],2132132132)" 
... 
7 = {[email protected]} "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文字列を解析しようとすることができます知っているが、私は途中で何らかの方法ミスを犯したと信じています。 フィールド名を参照として使用して、この構造体をオブジェクトに解析する方法はありますか? Play機能のビルドまたはそれに類するもの?

ありがとうございました!

+0

データがそのように送信される理由は、マルチパート/フォームデータ要求であるためです。それは、値が文字列であるいくつかの入力キーと値のペアを持つHTMLフォームと考えることができます。代わりに 'JSON.stringify()'を使ってデータをjson文字列に変換し、次にその文字列を読み込み、サーバライブラリを使ってjson文字列をモデルオブジェクトに変換します。 – danial

+0

@danial前に 'JSON.stringify()'を使っていましたが、画像をJSONに収める方法がわかりません。バイトを文字列として送信するだけでいいですか? – Atais

+0

このようなファイルは別に送信されません。{file:file、otherData:JSON.stringify(myData)} ' – danial

答えて

0

タイトルに記載されているとおり、私の場合はの画像を送信しました。ご希望通りに、私はプレビューと現在データベースに保存されているファイルも提示しています。

私はすべてのデータをJSON形式で両方の方法で送信することに決めました。画像がエンコードされ、JSON構造で送信されることを意味します。

上記の解決策が非常に便利であるにもかかわらず、実際には実装中に新しい問題が発生します。

  1. サーバーのPOST要求サイズの上限をすぐに超えます。 Playサーバーの場合、デフォルトの100kBを拡張することは可能ですが...
  2. 巨大な文字列として保存された画像には、送信/解析のエラーが多分あったため、すぐにデータの異常が発生しました。

    ありません。この
    {file: file, otherData: JSON.stringify(myData)}

    私のソリューション

    のように個別に送信されたファイルを持っている:私は@danialアドバイスを使用していたこの障害のあるソリューションに深く行くない

誰かが私と同様のアプローチを使用したい場合は、私はpres私の答え。 フロントエンド側では、ng-file-uploadライブラリを使用することに決めました。コンポーネントを有効にしngf-dropngf-selectでHTMLコンポーネントにバインド:

<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> 

をアップロードタグ内のIは、画像のプレビューを置きます。これは完璧に動作します。イメージが選択されていない場合は、dbに保存されたイメージを使用します。

データと画像はモデルを共有しません。アップロード機能は、以下のようになります。

return Upload.upload({ 
    url: url, 
    data: {file: images, data: angular.toJson(data)} 
}).then(function (resp) { 
    console.log(resp); 
}, function (error) { 
    console.log(error); 
}); 
上記のすべての私の出力データオブジェクト与えまとめる

:JSONを用意ケースクラスと一致し、ビルド - で解析され、サーバー側で

{ 
    "english":{ 
     "active":true, 
     "url":"http://google.com" 
    }, 
    "arabic":{ 
     "active":true, 
     "url":"http://google.com" 
    }, 
    "kurdish":{ 
     "active":true, 
     "url":"http://google.com" 
    } 
} 

をジャクソンパーサーでは、簡単にオブジェクトを操作することができます。画像を手動で選択する必要があります。

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)) 

お楽しみください!

関連する問題