Servlet从服务器加载视频文件

时间:2011-03-13 15:05:57

标签: java servlets

我有servlet从服务器加载视频文件并将其作为对http get请求的响应发送。在这里他的代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
{
    System.out.println("Start of doGet");

    FileSystemManager fsManager = null;
    try {
         fsManager = VFS.getManager();
    } catch (FileSystemException e) {

        e.printStackTrace();
    }


    // Get requested image by path info.
    String requestedImage = request.getPathInfo();

    // Check if file name is actually supplied to the request URI.
    if (requestedImage == null) {
        // Do your thing if the image is not supplied to the request URI.
        // Throw an exception, or send 404, or show default/warning image, or just ignore it.
        response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
        return;
    }

    FileObject basePath;

    try {

        basePath = fsManager.resolveFile( imagePath + URLDecoder.decode(requestedImage, "UTF-8"));


    } catch (FileSystemException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();

        return;
    }
    String baseName = basePath.getName().getBaseName();
    String contentType = getServletContext().getMimeType(baseName);
      // Init servlet response.
    response.reset();
    response.setBufferSize(DEFAULT_BUFFER_SIZE);
    response.setContentType(contentType);
    response.setHeader("Content-Length", String.valueOf(basePath.getContent().getSize()));


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

    int count = 0;
    try {
        // Open streams.
        FileContent fc = basePath.getContent(); 
        InputStream is = (InputStream) fc.getInputStream(); 
        input = new  BufferedInputStream(is, 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);
            count++;
        }
        System.out.println("no exception occurred");

    }
    catch(Exception e){
        System.out.println("while did " + count + " iterations befor exception occurred");
        System.out.println("Catched exception: " + e);
    }
    finally{    
        // Gently close streams.
        System.out.println("closing streams");
         close(input);
         close(output);

    }
}

当我从谷歌浏览器开始,例如http://localhost:8080/MyApp/video/VX-276.ogg时,我得到了这个输出:

开始doGet

虽然发生异常3次迭代

捕获的异常:ClientAbortException:java.net.SocketException:通过peer重置连接:套接字写入错误

关闭流

开始doGet

虽然发生异常4次迭代

捕获异常:ClientAbortException:java.net.SocketException:软件导致连接中止:套接字写入错误

关闭流

开始doGet

开始doGet

虽然发生异常发生224次迭代

捕获的异常:ClientAbortException:java.net.SocketException:通过peer重置连接:套接字写入错误

关闭流

虽然发生异常4次迭代

捕获异常:ClientAbortException:java.net.SocketException:软件导致连接中止:套接字写入错误

关闭流

开始doGet

虽然发生异常发生了12次迭代

捕获异常:ClientAbortException:java.net.SocketException:软件导致连接中止:套接字写入错误

关闭流

如何修复我的代码?

2 个答案:

答案 0 :(得分:1)

  

ClientAbortException:java.net.SocketException:peer by peer:socket write error

重置连接

webbrowser已中止连接。大概是因为最终用户按下 esc ,或者停止了视频,或者导航到其他页面,或者已经关闭了webbrowser。或者它毕竟是因为某种原因决定表现得像这样的webbrowser本身。

从服务器端开始,你无法对此做任何事情。反正我也不会记录它们。

为了最大限度地减少浪费的网络带宽,我强烈建议添加对字节范围请求的支持(读取:下载简历)。您可以找到一个基本示例here。您也可以将整个作业委托给servletcontainer的内置默认servlet,它应该已经支持了这个。您可以通过将带有视频的文件夹映射为另一个webapp上下文来实现。另请参阅this answer

答案 1 :(得分:1)

没有人会考虑浏览器上的缓存问题。

在servlet的开头使用这行代码。

response.addHeader(“Cache-Control”,“no-transform,max-age = 0”);