2013-09-02 4 views
6

Я пытаюсь загрузить видео файл на моем сервере, когда URL клиентского доступа похож на это:видео скачать/поток с помощью Java-сервлет

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

Я попробовал этот код. Но это не работает. Когда я посещаю сервлет, он загружает только файл Blank (0 size).

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

Я использовал BalusC-х fileservlet tutorial, но в моем случае я не имею объект файла, как InputStream только объект массив байтов.

помощь ..

+1

И вы проверили значение 'videoObjectData', чтобы узнать, что находится в нем после его инициализации? – chrylis

+0

yes, 'videoObjectData' содержит инициализированные данные – harshadura

ответ

7

сервлет, который вы нашли, действительно insuitable с целью потоковой передачи видеофайла. Он больше предназначен как простой сервлет для загрузки файлов для статических файлов, таких как PDF, XLS и т. Д.

Многие видеоплееры требуют, чтобы сервер поддерживал так называемые запросы диапазона HTTP. То есть он должен иметь возможность возвращать конкретный диапазон байтов видеофайла по запросу с заголовком Range. Например, только байты от индекса 1000 до 2000 в файле длиной 10000 байтов. Это необходимо, чтобы иметь возможность пропустить определенный диапазон видеопотока достаточно быстро, без необходимости загружать весь файл и/или улучшать скорость буферизации, создавая несколько HTTP-соединений, каждый из которых запрашивает другую часть видеофайла.

Это, однако, много дополнительного кода в сервлет, который требует хорошего понимания спецификации HTTP Range. Готовый к использованию пример предоставляется во вкусе этого extended file servlet тем же автором файлового сервлета, который вы нашли. В вашем конкретном случае, возможно, рекомендуется сначала сохранить файл на локальном диске на основе файловой системы на диске (например, на File#createTempFile() и на каком-то ключевом в сеансе HTTP), так что вам не нужно снова и снова получать его из внешней службы.

+1

Спасибо bunch @BalusC, теперь он работает с вашим последним сервлетами загрузки файлов с использованием java Temp-файла вместо передачи объекта массива байтов. Решение: https://gist.github.com/harshadura/6420565 – harshadura