2012-08-22 9 views
12

Piszę aplikację 2.0 java, która umożliwia użytkownikom przesyłanie plików. Pliki te przechowywane są na usługi trzeciej dostęp przy użyciu biblioteki Java, metoda używam w tym API ma następujący podpis:Przesyłanie pliku jako strumienia w strukturze gry 2.0

void store(InputStream stream, String path, String contentType) 

udało mi się zrobić przesłane pracy stosując następujący prosty kontroler:

public static Result uploadFile(String path) { 
    MultipartFormData body = request().body().asMultipartFormData(); 
    FilePart filePart = body.getFile("files[]"); 
    InputStream is = new FileInputStream(filePart.getFile()) 
    myApi.store(is,path,filePart.getContentType()); 
    return ok(); 
    } 

moim problemem jest to, że to rozwiązanie nie jest efektywne, ponieważ domyślnie przechowuje się grać ramowe wszystkie dane przesyłane przez klienta w pliku tymczasowym na serwerze następnie wywołuje metodę w kontroler mój uploadFile().

W tradycyjnym zastosowaniu serwletu bym pisemnej aplet zachowuje się w ten sposób:

myApi.store(request.getInputStream(), ...) 

Szukałem wszędzie i nie znaleźć żadnego rozwiązania. Najbliższym przykładem jest Why makes calling error or done in a BodyParser's Iteratee the request hang in Play Framework 2.0?, ale nie udało mi się go zmodyfikować tak, aby pasował do moich potrzeb.

Czy istnieje sposób w grze2, aby osiągnąć to zachowanie, tj. Posiadanie danych przesłanych przez klienta, aby przejść "przez" aplikację internetową bezpośrednio do innego systemu?

Dzięki.

Odpowiedz

12

byłem w stanie przesyłać dane do mojej trzeciej API za pomocą następującego kodu Scala Kontroler:

def uploadFile() = 
    Action(parse.multipartFormData(myPartHandler)) 
    { 
     request => Ok("Done") 
    } 

def myPartHandler: BodyParsers.parse.Multipart.PartHandler[MultipartFormData.FilePart[Result]] = { 
     parse.Multipart.handleFilePart { 
      case parse.Multipart.FileInfo(partName, filename, contentType) => 
      //Still dirty: the path of the file is in the partName... 
      String path = partName; 

      //Set up the PipedOutputStream here, give the input stream to a worker thread 
      val pos:PipedOutputStream = new PipedOutputStream(); 
      val pis:PipedInputStream = new PipedInputStream(pos); 
      val worker:UploadFileWorker = new UploadFileWorker(path,pis); 
      worker.contentType = contentType.get; 
      worker.start(); 

      //Read content to the POS 
      Iteratee.fold[Array[Byte], PipedOutputStream](pos) { (os, data) => 
       os.write(data) 
       os 
      }.mapDone { os => 
       os.close() 
       Ok("upload done") 
      } 
     } 
    } 

UploadFileWorker jest naprawdę proste klasy Java, który zawiera wywołanie API Thrid firm .

public class UploadFileWorker extends Thread { 
String path; 
PipedInputStream pis; 

public String contentType = ""; 

public UploadFileWorker(String path, PipedInputStream pis) { 
    super(); 
    this.path = path; 
    this.pis = pis; 
} 

public void run() { 
    try { 
     myApi.store(pis, path, contentType); 
     pis.close(); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
     try {pis.close();} catch (Exception ex2) {} 
    } 
} 

}

To nie jest całkowicie doskonały, ponieważ wolałbym odzyskać ścieżkę jako parametr do działania, ale nie byłem w stanie tego zrobić. W ten sposób dodałem fragment javascriptu, który aktualizuje nazwę pola wejściowego (a tym samym partName) i robi lewę.

+0

Czy jest to mimo to zrobić w Javie zamiast Scala? :( – by0

Powiązane problemy