2013-09-02 14 views
6

Próbuję pobrać plik wideo na moim serwerze, gdy dostęp URL klient podobny do tego:video download/strumień za pomocą apletu Java

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

Próbowałem tego kodu. Ale nie działa. Podczas odwiedzania serwletu pobierany jest tylko pusty plik (rozmiar 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(); 
     } 
    } 
} 

Użyłem BalusC na fileservlet tutorial ale w moim przypadku nie mam obiekt pliku jako InputStream właśnie obiektu tablica bajtów.

pomóc ..

+1

A czy sprawdziłeś wartość 'videoObjectData', aby zobaczyć, co jest w nim po zainicjowaniu? – chrylis

+0

tak, 'videoObjectData' zawiera zainicjalizowane dane – harshadura

Odpowiedz

7

Aplet który znalazłeś jest rzeczywiście insuitable w celu strumieniowego przesyłania pliku wideo. Jest bardziej przejrzysty jako prosty plik do pobierania plików statycznych, takich jak PDF, XLS itp.

Wiele odtwarzaczy wideo wymaga, aby serwer obsługiwał tak zwane żądania zakresu HTTP. To znaczy. musi mieć możliwość zwrócenia określonego zakresu bajtów pliku wideo przez żądanie z nagłówkiem Range. Na przykład tylko bajty z indeksu 1000 do 2000 na pliku o długości 10000 bajtów. Jest to obowiązkowe, aby można było przeskakiwać pewien zakres strumienia wideo wystarczająco szybko, bez konieczności pobierania całego pliku i/lub poprawy szybkości buforowania poprzez tworzenie wielu połączeń HTTP, z których każdy żąda innej części pliku wideo.

Jest to jednak dużo dodatkowego kodu w serwlecie, który wymaga dobrze zrozumienia specyfikacji HTTP Range. Gotowy do użycia przykład jest podany w smaku tego extended file servlet przez tego samego autora serwletu pliku, który znalazłeś. W twoim konkretnym przypadku prawdopodobnie zaleca się zapisanie pliku najpierw w pamięci podręcznej opartej na systemie plików na dysku lokalnym (na przykład przez File#createTempFile() i jakiś klucz w sesji HTTP), aby nie trzeba go było wielokrotnie uzyskiwać z usługi zewnętrznej.

+1

Dzięki za przydział @BalusC, działa teraz przy użyciu twojego najnowszego serwletu pobierania plików z podejściem do java Temp zamiast przekazywania obiektu tablicy bajtowej. rozwiązanie: https://gist.github.com/harshadura/6420565 – harshadura