2013-09-02 17 views
6

Sto cercando di scaricare un file video in mio assistente quando l'URL di accesso client simile a questo:video download/flusso utilizzando Java servlet

http://localhost:8088/openmrs/moduleServlet/patientnarratives/videoDownloadServlet?videoObsId=61 

Ho provato questo codice. Ma non funziona. Quando visito il servlet, scarica solo un file vuoto (dimensione 0).

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException 
{ 
    try { 
     Integer videoObsId = Integer.parseInt(request.getParameter("videoObsId")); 

     Obs complexObs = Context.getObsService().getComplexObs(videoObsId, OpenmrsConstants.RAW_VIEW); 
     ComplexData complexData = complexObs.getComplexData(); 
     Object object2 = complexData.getData(); // <-- an API used in my service. this simply returns an object. 

     byte[] videoObjectData = SerializationUtils.serialize(object2); 

     // Get content type by filename. 
     String contentType = null; 
     if (contentType == null) { 
      contentType = "application/octet-stream"; 
     } 

     // Init servlet response. 
     response.reset(); 
     response.setBufferSize(DEFAULT_BUFFER_SIZE); 
     response.setContentType(contentType); 
     response.setHeader("Content-Length", String.valueOf(videoObjectData.length)); 
     response.setHeader("Content-Disposition", "attachment; filename=\"" + "test.flv" + "\""); 

     // Prepare streams. 
     BufferedInputStream input = null; 
     BufferedOutputStream output = null; 

     try { 
      // Open streams. 
      input = new BufferedInputStream(new ByteArrayInputStream(videoObjectData), DEFAULT_BUFFER_SIZE);    
      output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE); 

      // Write file contents to response. 
      byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 
      int length; 
      while ((length = input.read(buffer)) > 0) { 
       output.write(buffer, 0, length); 
      } 
     } finally { 
      // Gently close streams. 
      close(output); 
      close(input); 
     } 
    } 

    // Add error handling above and remove this try/catch 
    catch (Exception e) { 
     log.error("unable to get file", e); 
    } 
} 
private static void close(Closeable resource) { 
    if (resource != null) { 
     try { 
      resource.close(); 
     } catch (IOException e) { 
      // Do your thing with the exception. Print it, log it or mail it. 
      e.printStackTrace(); 
     } 
    } 
} 

Ho usato BalusC di fileservlet tutorial ma nel mio caso io non sono oggetto file come InputStream appena l'oggetto array di byte.

aiuto ..

+1

E avete ispezionato il valore di 'videoObjectData' per vedere cosa c'è dopo averlo inizializzato? – chrylis

+0

yes, 'videoObjectData' contiene i dati inizializzati – harshadura

risposta

7

Il servlet che avete trovato è davvero insuitable allo scopo di streaming di un file video. È più intuitivo come semplice servlet per il download di file per file statici come PDF, XLS, ecc.

Un sacco di lettori video richiedono che il server supporti le cosiddette richieste di intervallo HTTP. Cioè deve essere in grado di restituire un intervallo di byte specifico del file video mediante una richiesta con un'intestazione Range. Ad esempio, solo i byte dall'indice 1000 fino al 2000 su un file lungo 10000 byte. Questo è obbligatorio per poter saltare un certo intervallo del flusso video abbastanza velocemente senza dover scaricare l'intero file e/o migliorare la velocità del buffer creando più connessioni HTTP che richiedono ciascuna una parte diversa del file video.

Questo è tuttavia un sacco di codice aggiuntivo nel servlet che richiede una buona comprensione della specifica HTTP Range. Un esempio pronto per l'uso è fornito in questo extended file servlet dallo stesso autore del servlet di file che hai trovato. Nel tuo caso specifico è forse consigliabile salvare il file su cache locale basata sul file system del disco (ad es. Da File#createTempFile() e qualche chiave nella sessione HTTP), in modo che non sia necessario ottenerlo dal servizio esterno ancora e ancora.

+1

Grazie bunch @BalusC, ora funziona utilizzando il servlet di download dei file più recente con l'approccio file java Temp invece di passare l'oggetto array byte. soluzione: https://gist.github.com/harshadura/6420565 – harshadura

Problemi correlati