2012-08-22 14 views
12

मैं एक प्ले 2.0 जावा एप्लिकेशन लिख रहा हूं जो उपयोगकर्ताओं को फ़ाइलों को अपलोड करने की अनुमति देता है।प्ले फ्रेमवर्क 2.0 में स्ट्रीम के रूप में फ़ाइल अपलोड करना

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

मैं निम्नलिखित सरल नियंत्रक का उपयोग काम कर अपलोड करने के लिए प्रबंधित किया है: उन फ़ाइलों मैं एक जावा पुस्तकालय का उपयोग कर का उपयोग एक तीसरे पक्ष सेवा पर जमा हो जाती, विधि मैं इस एपीआई में उपयोग निम्न हस्ताक्षर हैं:

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(); 
    } 

मेरी चिंता का विषय है कि इस समाधान क्योंकि डिफ़ॉल्ट रूप से कुशल नहीं है खेलने ढांचे भंडार सभी डेटा सर्वर पर एक अस्थायी फ़ाइल में ग्राहक द्वारा अपलोड की गई तो मेरे uploadFile() नियंत्रक में प्रणाली को बुलाती है।

एक पारंपरिक सर्वलेट आवेदन मैं एक सर्वलेट इस तरह से बर्ताव कर लिखा है | में:

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

मैं हर जगह खोज रहे होते हैं और किसी भी समाधान नहीं मिला। मैंने पाया सबसे नज़दीकी उदाहरण Why makes calling error or done in a BodyParser's Iteratee the request hang in Play Framework 2.0? है, लेकिन मुझे नहीं मिला कि मेरी जरूरतों को पूरा करने के लिए इसे कैसे संशोधित किया जाए।

क्या इस व्यवहार को प्राप्त करने के लिए play2 में कोई तरीका है, यानी क्लाइंट द्वारा अपलोड किए गए डेटा को वेब-एप्लिकेशन को सीधे "किसी अन्य सिस्टम" पर जाने के लिए अपलोड किया जा रहा है?

धन्यवाद।

उत्तर

12

मैं निम्नलिखित स्काला नियंत्रक कोड का उपयोग कर मेरी तीसरे पक्ष के एपीआई के लिए डेटा स्ट्रीम करने के लिए कर लिया है:

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 एक बहुत सरल जावा वर्ग है कि तृतीय-पक्ष एपीआई के लिए कॉल शामिल है ।

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

}

यह पूरी तरह से सही नहीं है क्योंकि मैं कार्रवाई करने के लिए एक पैरामीटर के रूप पथ ठीक करने के लिए पसंद करते हैं, लेकिन मैं ऐसा करने में सक्षम नहीं किया गया है। इस प्रकार मैंने जावास्क्रिप्ट का एक टुकड़ा जोड़ा है जो इनपुट फ़ील्ड (और इस प्रकार partName) का नाम अपडेट करता है और यह चाल करता है।

+0

क्या स्कैला के बजाए जावा में ऐसा करने के लिए वैसे भी है? :( – by0