2013-02-23 12 views
7

obecnie używam następujących z PLAY2/Scala użyciu narzędzia FileUploader JavaScript, żeby przesłać plik do mojego serwera:Wyciąganie plików z MultipartFormData w pamięci w PLAY2/Scala

def fileUploader = Action(parse.multipartFormData) { request => 
    request.body.file("qqfile").map { picture => 
    import java.io.File 
    val filename = picture.filename 
    val contentType = picture.contentType 
    picture.ref.moveTo(new File("/tmp",filename)) 
    Ok(Json.toJson(Map("success" -> "true"))) 
    }.getOrElse { 
    Ok(Json.toJson(Map("error" -> "error occured"))) 
    } 
} 

mam do czynienia jedynie z małe pliki (< 10MB) i chcę użyć Casbah do zapisania tych plików bezpośrednio w Mongo Document lub GridFS za pomocą sterowników Mongo. Zdaję sobie sprawę, że mogłem po prostu odczytać zapisany plik z dysku, ale czy istnieje sposób na obsłużenie tego wszystkiego z pamięci bez buforowania pliku na dysku?

Dokumentacja odtwarzania tutaj zaleca napisanie niestandardowego BodyParser (http://www.playframework.com/documentation/2.1.0/ScalaFileUpload), ale nie wydaje się, aby istniała jakakolwiek dokumentacja, jak go napisać. Nie było jasne, jak interfejs API/implementacja działała od Scaladoców. Próbowałem patrząc na kodzie źródłowym MultiPartFormData, aby zobaczyć jak to działa, ale nie może wydawać się znaleźć w ich Git repo:

https://github.com/playframework/Play20/tree/master/framework/src/play/src/main/scala/play/api/mvc

Rozglądałem się trochę, ale nie może wydawać znaleźć dobry przykład.

+1

Opcja 'multipartFormData' parser ciało można znaleźć tutaj: https://github.com/playframework/Play20/blob/2.1.0/framework/ src/play/src/main/scala/play/api/mvc/ContentTypes.scala # L541 – EECOLOR

Odpowiedz

12

Nietestowane Multipart przedmiotem BodyParsers robi dużo pracy dla nas. Pierwszą rzeczą, którą musimy zrobić, jest napisanie programu obsługi dla urządzenia FilePart. Zakładam tutaj, że chcesz części pliku Array[Byte].

def handleFilePartAsByteArray: PartHandler[FilePart[Array[Byte]]] = 
    handleFilePart { 
    case FileInfo(partName, filename, contentType) => 
     // simply write the data to the a ByteArrayOutputStream 
     Iteratee.fold[Array[Byte], ByteArrayOutputStream](
     new ByteArrayOutputStream()) { (os, data) => 
      os.write(data) 
      os 
     }.mapDone { os => 
      os.close() 
      os.toByteArray 
     } 
    } 

Następnym krokiem jest określenie swój parser ciała:

def multipartFormDataAsBytes:BodyParser[MultipartFormData[Array[Byte]]] = 
    multipartFormData(handleFilePartAsByteArray) 

Następnie, w celu wykorzystania go określić go na ciebie Action:

def fileUploader = Action(multipartFormDataAsBytes) { request => 
    request.body.files foreach { 
    case FilePart(key, filename, contentType, bytes) => // do something 
    } 
    Ok("done") 
} 

Niektóre rodzaje i metody powyższe fragmenty kodu są nieco trudne do znalezienia. Powyżej znajduje się pełna lista importu w przypadku trzeba go:

import play.api.mvc.BodyParsers.parse.Multipart.PartHandler 
import play.api.mvc.BodyParsers.parse.Multipart.handleFilePart 
import play.api.mvc.BodyParsers.parse.Multipart.FileInfo 
import play.api.mvc.BodyParsers.parse.multipartFormData 
import play.api.mvc.MultipartFormData.FilePart 
import play.api.libs.iteratee.Iteratee 
import java.io.ByteArrayOutputStream 
import play.api.mvc.BodyParser 
import play.api.mvc.MultipartFormData 
Powiązane problemy